Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions packages/boxel-icons/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,12 @@
"@babel/runtime": "catalog:",
"@cardstack/eslint-plugin-boxel": "workspace:*",
"@cardstack/local-types": "workspace:*",
"@lucide/lab": "^0.1.2",
"@tabler/icons": "^3.19.0",
"@embroider/addon-dev": "^5.0.0",
"@embroider/macros": "^1.16.5",
"@embroider/macros": "^1.20.5",
"@glint/ember-tsc": "catalog:",
"@lucide/lab": "^0.1.2",
"@rollup/plugin-babel": "catalog:",
"@tabler/icons": "^3.19.0",
"@tsconfig/ember": "3.0.1",
"@typescript-eslint/eslint-plugin": "catalog:",
"@typescript-eslint/parser": "catalog:",
Expand All @@ -71,8 +72,7 @@
"prettier-plugin-ember-template-tag": "catalog:",
"rollup": "catalog:",
"rollup-plugin-copy": "catalog:",
"svgo": "catalog:",
"@glint/ember-tsc": "catalog:"
"svgo": "catalog:"
},
"peerDependencies": {
"@ember/string": "catalog:",
Expand Down
16 changes: 5 additions & 11 deletions packages/boxel-ui/babel.config.mjs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import { dirname } from 'node:path';
import { fileURLToPath } from 'node:url';

import {
babelCompatSupport,
templateCompatSupport,
} from '@embroider/compat/babel';
import { buildMacros } from '@embroider/macros/babel';

const macros = buildMacros();

/**
* This babel config drives the vite dev/test pipeline (see vite.config.mjs).
Expand All @@ -26,13 +25,8 @@ export default {
[
'babel-plugin-ember-template-compilation',
{
enableLegacyModules: [
'ember-cli-htmlbars',
'ember-cli-htmlbars-inline-precompile',
'htmlbars-inline-precompile',
],
transforms: [
...templateCompatSupport(),
...macros.templateMacros,
'glimmer-scoped-css/ast-transform',
],
},
Expand All @@ -55,7 +49,7 @@ export default {
regenerator: false,
},
],
...babelCompatSupport(),
...macros.babelMacros,
],

generatorOpts: {
Expand Down
21 changes: 0 additions & 21 deletions packages/boxel-ui/config/environment.js

This file was deleted.

2 changes: 1 addition & 1 deletion packages/boxel-ui/docs-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@
"@embroider/config-meta-loader": "^1.0.0",
"@embroider/core": "^4.4.7",
"@embroider/legacy-inspector-support": "^0.1.3",
"@embroider/macros": "^1.16.5",
"@embroider/macros": "^1.20.5",
"@embroider/test-setup": "^4.0.0",
"@embroider/vite": "^1.7.2",
"@glimmer/component": "catalog:",
Expand Down
15 changes: 0 additions & 15 deletions packages/boxel-ui/ember-cli-build.js

This file was deleted.

15 changes: 5 additions & 10 deletions packages/boxel-ui/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@
"decorator-transforms": "catalog:",
"dompurify": "catalog:",
"ember-animated": "catalog:",
"ember-basic-dropdown": "8.0.4",
"ember-basic-dropdown": "^9.0.0",
"ember-concurrency": "catalog:",
"ember-concurrency-ts": "catalog:",
"ember-css-url": "^1.0.0",
"ember-draggable-modifiers": "^1.0.0",
"ember-focus-trap": "^1.0.1",
"ember-freestyle": "catalog:",
"ember-modifier": "^4.1.0",
"ember-power-calendar": "^1.2.0",
"ember-power-calendar-moment": "^1.0.2",
"ember-power-select": "^8.0.0",
"ember-power-calendar": "^2.0.0",
"ember-power-calendar-moment": "^1.0.4",
"ember-power-select": "^9.0.0",
"ember-resize-modifier": "^0.7.1",
"ember-sortable": "^5.3.1",
"ember-velcro": "^2.1.3",
Expand All @@ -77,13 +77,11 @@
"@babel/runtime": "catalog:",
"@cardstack/eslint-plugin-boxel": "workspace:*",
"@cardstack/local-types": "workspace:*",
"@ember/optional-features": "^2.0.0",
"@ember/test-helpers": "catalog:",
"@embroider/addon-dev": "^8.0.0",
"@embroider/compat": "^4.1.17",
"@embroider/config-meta-loader": "^1.0.0",
"@embroider/core": "^4.4.7",
"@embroider/macros": "~1.16.5",
"@embroider/macros": "^1.20.5",
"@embroider/vite": "^1.7.2",
"@eslint/js": "^9.17.0",
"@glimmer/component": "catalog:",
Expand All @@ -97,9 +95,6 @@
"babel-plugin-ember-template-compilation": "catalog:",
"concurrently": "catalog:",
"ember-a11y-testing": "^8.0.0",
"ember-cli": "^5.4.1",
"ember-cli-babel": "^8.2.0",
"ember-cli-htmlbars": "^6.3.0",
"ember-qunit": "catalog:",
"ember-source": "catalog:",
"ember-strict-application-resolver": "^0.1.0",
Expand Down
11 changes: 6 additions & 5 deletions packages/boxel-ui/src/components/dropdown/index.gts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import { action } from '@ember/object';
import { guidFor } from '@ember/object/internals';
import type Owner from '@ember/owner';
import Component from '@glimmer/component';
import BasicDropdown, {
type Dropdown,
} from 'ember-basic-dropdown/components/basic-dropdown';
import BasicDropdown from 'ember-basic-dropdown/components/basic-dropdown';
import type { Dropdown } from 'ember-basic-dropdown/types';
import focusTrap from 'ember-focus-trap/modifiers/focus-trap';
import {
type FunctionBasedModifier,
Expand Down Expand Up @@ -185,8 +184,10 @@ class BoxelDropdown extends Component<Signature> {
this.themeObserver = null;
}

@action registerAPI(publicAPI: DropdownAPI) {
this.args.registerAPI?.(publicAPI);
@action registerAPI(publicAPI: DropdownAPI | null) {
if (publicAPI) {
this.args.registerAPI?.(publicAPI);
}
}

@action onMouseLeave(dropdown?: Dropdown) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { on } from '@ember/modifier';
import { action } from '@ember/object';
import Component from '@glimmer/component';
import type { Select } from 'ember-power-select/components/power-select';
import type { Select } from 'ember-power-select/types';

import BoxelButton from '../button/index.gts';

Expand Down
75 changes: 37 additions & 38 deletions packages/boxel-ui/src/components/multi-select/index.gts
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,48 @@ import 'ember-power-select/styles';

import Component from '@glimmer/component';
import type { ComponentLike } from '@glint/template';
import type {
PowerSelectArgs,
Select,
} from 'ember-power-select/components/power-select';
import type { PowerSelectArgs } from 'ember-power-select/components/power-select';
import PowerSelect from 'ember-power-select/components/power-select';
import BeforeOptions from 'ember-power-select/components/power-select/before-options';
import type {
Option,
PowerSelectAfterOptionsSignature,
PowerSelectSelectedItemSignature,
Select,
} from 'ember-power-select/types';

import { cn, not } from '../../helpers.gts';
import { BoxelAfterOptionsComponent } from './after-options.gts';
import BoxelSelectedItem, {
type SelectedItemSignature,
} from './selected-item.gts';
import BoxelMultiSelectDefaultTrigger, {
type TriggerComponentSignature,
} from './trigger.gts';

export interface BoxelMultiSelectArgs<ItemT> extends PowerSelectArgs {
afterOptionsComponent?: ComponentLike<any>;
ariaLabel?: string;
beforeOptionsComponent?: ComponentLike<any>;
closeOnSelect?: boolean;
destination?: string;
disabled?: boolean;
dropdownClass?: string;
extra?: any;
matchTriggerWidth?: boolean;
onBlur?: (select: Select, e: Event) => boolean | undefined;
onClose?: (select: Select, e: Event) => boolean | undefined;
onOpen?: (select: Select, e: Event) => boolean | undefined;
options: ItemT[];
placeholder?: string;
renderInPlace?: boolean;
searchEnabled?: boolean;
searchField?: string;
selected: ItemT[];
selectedItemComponent?: ComponentLike<SelectedItemSignature<ItemT>>;
triggerComponent?: ComponentLike<TriggerComponentSignature<ItemT>>;
const DefaultAfterOptions =
BoxelAfterOptionsComponent as unknown as ComponentLike<
PowerSelectAfterOptionsSignature<any, any, true>
>;
import BoxelSelectedItem from './selected-item.gts';

// The default subcomponents are generic classes whose inferred ComponentLike
// shapes glint cannot match against power-select's expected unions; their
// signatures are structurally compatible (verified by the suite), so pin
// them to the expected member types once here.
const DefaultSelectedItem = BoxelSelectedItem as unknown as ComponentLike<
PowerSelectSelectedItemSignature<any, any, true>
>;
import BoxelMultiSelectDefaultTrigger from './trigger.gts';

// Everything else is inherited from ember-power-select's own args;
// options/selected are re-declared only to make them required.
export interface BoxelMultiSelectArgs<ItemT> extends PowerSelectArgs<
ItemT,
true
> {
options: NonNullable<PowerSelectArgs<ItemT, true>['options']>;
selected: NonNullable<PowerSelectArgs<ItemT, true>['selected']>;
}

export interface Signature<ItemT> {
Args: BoxelMultiSelectArgs<ItemT>;
Blocks: {
default: [any, Select];
default: [Option<ItemT>, Select<ItemT, true>];
};
Element: HTMLElement;
}
Expand Down Expand Up @@ -100,8 +99,8 @@ export class BoxelMultiSelectBasic<ItemT> extends Component<Signature<ItemT>> {
@afterOptionsComponent={{@afterOptionsComponent}}
@beforeOptionsComponent={{if
@beforeOptionsComponent
(component @beforeOptionsComponent)
(component BeforeOptions)
@beforeOptionsComponent
BeforeOptions
}}
...attributes
as |option select|
Expand Down Expand Up @@ -216,11 +215,11 @@ export default class BoxelMultiSelect<ItemT> extends Component<
@selectedItemComponent={{if
@selectedItemComponent
@selectedItemComponent
(component BoxelSelectedItem)
DefaultSelectedItem
}}
@triggerComponent={{component BoxelMultiSelectDefaultTrigger}}
@beforeOptionsComponent={{component BeforeOptions}}
@afterOptionsComponent={{component BoxelAfterOptionsComponent}}
@triggerComponent={{BoxelMultiSelectDefaultTrigger}}
@beforeOptionsComponent={{BeforeOptions}}
@afterOptionsComponent={{DefaultAfterOptions}}
...attributes
as |option select|
>
Expand Down
25 changes: 13 additions & 12 deletions packages/boxel-ui/src/components/multi-select/selected-item.gts
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,35 @@ import { fn } from '@ember/helper';
import { on } from '@ember/modifier';
import { action } from '@ember/object';
import Component from '@glimmer/component';
import type { Select } from 'ember-power-select/components/power-select';
import type { Option, Select } from 'ember-power-select/types';

import IconX from '../../icons/icon-x.gts';
import Pill from '../pill/index.gts';

// Inside the trigger component, the selected item component is called within in ember-power-select
// It only passes option, select
// We follow the same convention when defining our own selected item component
// Invoked per selected item by the trigger; the arg names follow
// ember-power-select's own selected-item contract (@selected, @select) so
// custom components typed against either signature are interchangeable.
export interface SelectedItemSignature<ItemT> {
Args: {
option: any;
select: Select & {
extra?: unknown;
select: Select<ItemT, true> & {
actions: {
remove: (item: ItemT) => void;
remove?: (item: Option<ItemT>) => void;
};
};
selected: Option<ItemT>;
};
Blocks: {
default: [ItemT, Select];
default: [Option<ItemT>, Select<ItemT, true>];
};
Element: HTMLDivElement;
Element: HTMLElement;
}

export default class BoxelSelectedItem<ItemT> extends Component<
SelectedItemSignature<ItemT>
> {
@action
remove(item: ItemT, event: MouseEvent) {
remove(item: Option<ItemT>, event: MouseEvent) {
// Do not remove these event methods
// This is to ensure that the close/click event from selected item does not bubble up to the trigger
// and cause the dropdown to close
Expand All @@ -46,14 +47,14 @@ export default class BoxelSelectedItem<ItemT> extends Component<
<div class='ember-power-select-multiple-option'>
<Pill class='boxel-selected-option'>
<:default>
{{yield @option @select}}
{{yield @selected @select}}
</:default>
<:iconRight>
{{! TODO: Replace with icon button }}
<button
type='button'
class='boxel-multi-select__remove-button'
{{on 'click' (fn this.remove @option)}}
{{on 'click' (fn this.remove @selected)}}
aria-label='Remove item'
>

Expand Down
Loading
Loading