ionbase-ui 0.81.1 → 0.86.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/dist/components/Checkbox.d.ts +39 -0
  2. package/dist/components/Checkbox.d.ts.map +1 -1
  3. package/dist/components/Checkbox.js +77 -4
  4. package/dist/components/Checkbox.js.map +1 -1
  5. package/dist/components/Fieldset.d.ts +62 -0
  6. package/dist/components/Fieldset.d.ts.map +1 -0
  7. package/dist/components/Fieldset.js +58 -0
  8. package/dist/components/Fieldset.js.map +1 -0
  9. package/dist/components/Menu.d.ts +87 -24
  10. package/dist/components/Menu.d.ts.map +1 -1
  11. package/dist/components/Menu.js +245 -28
  12. package/dist/components/Menu.js.map +1 -1
  13. package/dist/components/PageHeader.d.ts +59 -0
  14. package/dist/components/PageHeader.d.ts.map +1 -0
  15. package/dist/components/PageHeader.js +29 -0
  16. package/dist/components/PageHeader.js.map +1 -0
  17. package/dist/components/Radio.d.ts +14 -0
  18. package/dist/components/Radio.d.ts.map +1 -1
  19. package/dist/components/Radio.js +15 -4
  20. package/dist/components/Radio.js.map +1 -1
  21. package/dist/components/SearchField.d.ts +36 -0
  22. package/dist/components/SearchField.d.ts.map +1 -0
  23. package/dist/components/SearchField.js +76 -0
  24. package/dist/components/SearchField.js.map +1 -0
  25. package/dist/components/index.d.ts +10 -4
  26. package/dist/components/index.d.ts.map +1 -1
  27. package/dist/components/index.js +5 -2
  28. package/dist/components/index.js.map +1 -1
  29. package/dist/figma-descriptions.json +96 -76
  30. package/dist/figma-map.json +272 -39
  31. package/dist/meta/Checkbox.json +8 -6
  32. package/dist/meta/CheckboxGroup.json +268 -0
  33. package/dist/meta/Divider.json +2 -2
  34. package/dist/meta/Fieldset.json +162 -0
  35. package/dist/meta/Menu.json +201 -27
  36. package/dist/meta/MenuItem.json +137 -17
  37. package/dist/meta/MenuSection.json +90 -0
  38. package/dist/meta/MenuTrigger.json +177 -0
  39. package/dist/meta/PageHeader.json +169 -0
  40. package/dist/meta/Radio.json +0 -1
  41. package/dist/meta/RadioGroup.json +59 -7
  42. package/dist/meta/SearchField.json +487 -0
  43. package/dist/meta/Stepper.json +2 -2
  44. package/dist/meta/Tabs.json +3 -3
  45. package/dist/meta/components.json +1917 -217
  46. package/dist/meta/contrast.json +594 -90
  47. package/dist/meta/index.json +89 -10
  48. package/dist/meta/patterns/DataTable.json +14 -6
  49. package/dist/meta/patterns/Form.json +27 -2
  50. package/dist/meta/patterns/PageShell.json +18 -5
  51. package/dist/meta/patterns/index.json +5 -2
  52. package/dist/styles/fieldset.css +65 -0
  53. package/dist/styles/index.css +3 -0
  54. package/dist/styles/menu.css +153 -32
  55. package/dist/styles/page-header.css +94 -0
  56. package/dist/styles/radio.css +0 -20
  57. package/dist/styles/search-field.css +70 -0
  58. package/llms.txt +2 -2
  59. package/package.json +1 -1
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "ionbase-ui",
3
- "version": "0.81.1",
3
+ "version": "0.86.0",
4
4
  "usage": "Pick a component here, then read dist/meta/<Name>.json for its full contract.",
5
5
  "hooks": [
6
6
  "useAgentRun",
@@ -298,6 +298,28 @@
298
298
  "detail": "dist/meta/Checkbox.json",
299
299
  "hasIntent": true
300
300
  },
301
+ "CheckboxGroup": {
302
+ "summary": "A set of checkboxes answering one question. Owns the selected values, the group's label, help and error, and \"select at least one\".",
303
+ "status": "stable",
304
+ "variants": {
305
+ "size": [
306
+ "sm",
307
+ "md",
308
+ "lg"
309
+ ],
310
+ "intent": [
311
+ "neutral",
312
+ "danger",
313
+ "brand"
314
+ ],
315
+ "orientation": [
316
+ "vertical",
317
+ "horizontal"
318
+ ]
319
+ },
320
+ "detail": "dist/meta/CheckboxGroup.json",
321
+ "hasIntent": true
322
+ },
301
323
  "Citation": {
302
324
  "summary": "The inline source marker. The visible number is for the eye; the accessible name is the sentence.",
303
325
  "status": "stable",
@@ -388,8 +410,8 @@
388
410
  "status": "stable",
389
411
  "variants": {
390
412
  "orientation": [
391
- "horizontal",
392
- "vertical"
413
+ "vertical",
414
+ "horizontal"
393
415
  ]
394
416
  },
395
417
  "detail": "dist/meta/Divider.json",
@@ -433,6 +455,18 @@
433
455
  "detail": "dist/meta/EmptyState.json",
434
456
  "hasIntent": true
435
457
  },
458
+ "Fieldset": {
459
+ "summary": "A <fieldset>/<legend> that groups related fields under one label, one description and one error — an address, a pair of limits, a date typed as two fields.",
460
+ "status": "stable",
461
+ "variants": {
462
+ "orientation": [
463
+ "vertical",
464
+ "horizontal"
465
+ ]
466
+ },
467
+ "detail": "dist/meta/Fieldset.json",
468
+ "hasIntent": true
469
+ },
436
470
  "FileUpload": {
437
471
  "summary": "A drop target wrapped around a real file input, with client-side accept and size checks.",
438
472
  "status": "stable",
@@ -550,19 +584,40 @@
550
584
  "hasIntent": true
551
585
  },
552
586
  "Menu": {
553
- "summary": "The list surface only — no trigger, no anchor, no open state. Positioning it is the caller's job.",
587
+ "summary": "An ARIA menu: one tab stop, arrow keys, typeahead, and optional single or multiple selection. Children are MenuItem and MenuSection. Inside a MenuTrigger it floats, opens and closes, and can open submenus; on its own it renders in flow.",
554
588
  "status": "stable",
555
589
  "variants": {},
556
590
  "detail": "dist/meta/Menu.json",
557
591
  "hasIntent": true
558
592
  },
559
593
  "MenuItem": {
560
- "summary": "One row in a Menu. A real <button> inside an <li>, with an optional leading icon and a trailing selected check.",
594
+ "summary": "One row of a Menu. A collection element: Menu reads its props and draws the row as `menuitem`, `menuitemradio` or `menuitemcheckbox`.",
561
595
  "status": "stable",
562
596
  "variants": {},
563
597
  "detail": "dist/meta/MenuItem.json",
564
598
  "hasIntent": true
565
599
  },
600
+ "MenuSection": {
601
+ "summary": "A named group of MenuItems. Re-exported from react-stately's collection Section — `title` is Figma's Menu Section Title.",
602
+ "status": "stable",
603
+ "variants": {},
604
+ "detail": "dist/meta/MenuSection.json",
605
+ "hasIntent": true
606
+ },
607
+ "MenuTrigger": {
608
+ "summary": "A Button that opens a Menu. The \"⋯\" overflow menu is this with an icon-only Button. Owns open state, positioning, focus, and the ARIA link between the two.",
609
+ "status": "stable",
610
+ "variants": {
611
+ "placement": [
612
+ "bottom start",
613
+ "bottom end",
614
+ "top start",
615
+ "top end"
616
+ ]
617
+ },
618
+ "detail": "dist/meta/MenuTrigger.json",
619
+ "hasIntent": true
620
+ },
566
621
  "Modal": {
567
622
  "summary": "A focus-trapping dialog. Renders nothing when closed and portals when open.",
568
623
  "status": "stable",
@@ -601,6 +656,13 @@
601
656
  "detail": "dist/meta/NumberInput.json",
602
657
  "hasIntent": true
603
658
  },
659
+ "PageHeader": {
660
+ "summary": "The top of a page: breadcrumb, the page's h1, a description, the record's status, and the page's actions. Not a landmark — main is, named by this title.",
661
+ "status": "stable",
662
+ "variants": {},
663
+ "detail": "dist/meta/PageHeader.json",
664
+ "hasIntent": true
665
+ },
604
666
  "Pagination": {
605
667
  "summary": "Page navigation for a table or list. Renders prev/next arrows, a truncated run of page numbers, and an optional rows-per-page Select.",
606
668
  "status": "stable",
@@ -707,9 +769,13 @@
707
769
  "hasIntent": true
708
770
  },
709
771
  "RadioGroup": {
710
- "summary": "A <fieldset>/<legend> group of mutually exclusive options. Owns the shared name and the selected value.",
772
+ "summary": "A <fieldset>/<legend> group of mutually exclusive options. Owns the shared name and the selected value, and the group's label, help and error.",
711
773
  "status": "stable",
712
774
  "variants": {
775
+ "orientation": [
776
+ "vertical",
777
+ "horizontal"
778
+ ],
713
779
  "size": [
714
780
  "sm",
715
781
  "md",
@@ -736,6 +802,19 @@
736
802
  "detail": "dist/meta/ScrollProgress.json",
737
803
  "hasIntent": true
738
804
  },
805
+ "SearchField": {
806
+ "summary": "A text field for a search query: role=\"searchbox\", Enter submits, Escape clears, and a clear button once there is something to clear. Input's box and sizes.",
807
+ "status": "stable",
808
+ "variants": {
809
+ "size": [
810
+ "sm",
811
+ "md",
812
+ "lg"
813
+ ]
814
+ },
815
+ "detail": "dist/meta/SearchField.json",
816
+ "hasIntent": true
817
+ },
739
818
  "SegmentedControl": {
740
819
  "summary": "Pick one of two to five options, all visible at once. A radio group drawn as a segmented track — it sets a value and controls no panel.",
741
820
  "status": "stable",
@@ -852,8 +931,8 @@
852
931
  "status": "stable",
853
932
  "variants": {
854
933
  "orientation": [
855
- "horizontal",
856
- "vertical"
934
+ "vertical",
935
+ "horizontal"
857
936
  ]
858
937
  },
859
938
  "detail": "dist/meta/Stepper.json",
@@ -962,8 +1041,8 @@
962
1041
  "lg"
963
1042
  ],
964
1043
  "orientation": [
965
- "horizontal",
966
- "vertical"
1044
+ "vertical",
1045
+ "horizontal"
967
1046
  ]
968
1047
  },
969
1048
  "detail": "dist/meta/Tabs.json",
@@ -15,12 +15,12 @@
15
15
  "Button",
16
16
  "Badge",
17
17
  "Alert",
18
- "Input",
18
+ "SearchField",
19
19
  "TagGroup"
20
20
  ],
21
21
  "structure": [
22
- "A toolbar above the table: a search Input, filter controls, and the bulk-action Buttons that appear once something is selected.",
23
- "Under the toolbar, once any filter is applied: a TagGroup of the active filters, each removable on its own, beside a Clear all Button. When the last one goes the row goes with it, so move focus to the search Input.",
22
+ "A toolbar above the table: a SearchField (size sm, with an aria-label naming what it searches), filter controls, and the bulk-action Buttons that appear once something is selected.",
23
+ "Under the toolbar, once any filter is applied: a TagGroup of the active filters, each removable on its own, beside a Clear all Button. When the last one goes the row goes with it, so move focus to the SearchField.",
24
24
  "Table with a TableHead whose first cell carries the select-all Checkbox, and a TableBody whose rows each carry their own.",
25
25
  "Sortable columns: every header that sorts gets `sortDirection` — the current direction on the sorted column, `none` on the others — so each shows it can be sorted before anyone tries.",
26
26
  "One region below the table for pagination or a load-more Button.",
@@ -80,13 +80,17 @@
80
80
  "title",
81
81
  "actions"
82
82
  ],
83
- "Input": [
84
- "leadingIcon"
85
- ],
86
83
  "TagGroup": [
87
84
  "label",
88
85
  "items",
89
86
  "onRemove"
87
+ ],
88
+ "SearchField": [
89
+ "size",
90
+ "value",
91
+ "onChange",
92
+ "placeholder",
93
+ "aria-label"
90
94
  ]
91
95
  },
92
96
  "variantsUsed": {
@@ -152,6 +156,10 @@
152
156
  {
153
157
  "dont": "sorting only the current page of a paged table",
154
158
  "why": "the reader sees \"A–Z\" and takes it as the whole list; send the sort to the server, which knows every row"
159
+ },
160
+ {
161
+ "dont": "an Input with type=\"search\" and a magnifier icon as the table's search",
162
+ "why": "it has no searchbox role, no Escape to clear and no labelled clear button — SearchField is the same box with that behaviour"
155
163
  }
156
164
  ]
157
165
  }
@@ -9,6 +9,8 @@
9
9
  "Input",
10
10
  "Select",
11
11
  "Checkbox",
12
+ "CheckboxGroup",
13
+ "Fieldset",
12
14
  "Radio",
13
15
  "RadioGroup",
14
16
  "Toggle",
@@ -21,6 +23,7 @@
21
23
  "structure": [
22
24
  "Fields in a single column. Two columns only for genuinely paired values, and they stack below the mobile breakpoint.",
23
25
  "Each field carries its own label and, when invalid, its own errorMessage — the message sits with the control it is about.",
26
+ "Related fields that answer one question — an address, a pair of limits, a set of checkboxes — sit in a Fieldset, CheckboxGroup or RadioGroup, so the question is announced with each field and a group-level error has somewhere to live.",
24
27
  "An error summary Alert above the form after a failed submit, listing each invalid field as a link to it.",
25
28
  "A submit Button and a cancel Link or Button, in that reading order, at the end."
26
29
  ],
@@ -70,7 +73,23 @@
70
73
  "label",
71
74
  "name",
72
75
  "value",
73
- "onChange"
76
+ "onChange",
77
+ "isInvalid",
78
+ "errorMessage",
79
+ "isRequired"
80
+ ],
81
+ "CheckboxGroup": [
82
+ "label",
83
+ "value",
84
+ "onChange",
85
+ "isInvalid",
86
+ "errorMessage",
87
+ "isRequired"
88
+ ],
89
+ "Fieldset": [
90
+ "label",
91
+ "isInvalid",
92
+ "errorMessage"
74
93
  ],
75
94
  "Checkbox": [
76
95
  "isDisabled"
@@ -104,7 +123,8 @@
104
123
  "a visible `label` on every field, or `aria-label` where the label is genuinely elsewhere",
105
124
  "`isInvalid` alongside `errorMessage` — the message alone styles the field without announcing it as invalid",
106
125
  "focus moved to the error summary after a failed submit",
107
- "`isRequired` on required fields rather than an asterisk in the label text"
126
+ "`isRequired` on required fields rather than an asterisk in the label text",
127
+ "a group-level error on the CheckboxGroup, RadioGroup or Fieldset it is about — \"choose at least one\" belongs to the set, not to its first box"
108
128
  ],
109
129
  "notes": [
110
130
  "Validate on blur and on submit, not on every keystroke: an error that appears while the user is still typing the value is wrong more often than right."
@@ -131,6 +151,11 @@
131
151
  "dont": "a Toggle inside a form that is submitted",
132
152
  "do": "Checkbox",
133
153
  "why": "a switch says the change already took effect"
154
+ },
155
+ {
156
+ "dont": "a row of Checkboxes under a heading, with the error in a paragraph beneath",
157
+ "do": "<CheckboxGroup label=\"…\" isRequired isInvalid errorMessage=\"…\">",
158
+ "why": "the heading is not announced with the boxes and the error is attached to none of them"
134
159
  }
135
160
  ]
136
161
  }
@@ -14,6 +14,7 @@
14
14
  "Logo",
15
15
  "LogoMark",
16
16
  "Avatar",
17
+ "PageHeader",
17
18
  "Button",
18
19
  "Divider",
19
20
  "ToastProvider",
@@ -22,15 +23,15 @@
22
23
  ],
23
24
  "structure": [
24
25
  "Header at the top with the brand in `brand`, primary navigation in `center` and account actions in `end`.",
25
- "One <main> content region, named, holding the page's own heading as its h1.",
26
+ "One <main> content region, named by the page's PageHeader: pass PageHeader a `titleId` and point <main aria-labelledby> at it. The PageHeader's title is the page's h1.",
26
27
  "ToastProvider mounted once around the whole shell, not per route.",
27
- "Breadcrumbs, when present, sit inside <main> above the h1 — they describe where the content is, not where the chrome is.",
28
+ "Breadcrumbs, when present, go in PageHeader's `breadcrumb` slot, inside <main> above the h1 — they describe where the content is, not where the chrome is.",
28
29
  "When navigation is hierarchical or longer than a header row holds, a Sidebar replaces the NavItems in Header's `center`: Header keeps the brand and account actions, and the Sidebar sits beside <main> as the primary navigation. Below the tablet breakpoint the same Sidebar moves into a Drawer opened by Header's own toggle with `menuType=\"dialog\"` — one copy, not two, and one menu button.",
29
30
  "A CommandPalette, when the product has one, is mounted once inside the shell beside ToastProvider, not per route. Header's `end` carries a Search button showing <Kbd shortcut=\"mod+k\" /> — the visible door for anyone who does not know the shortcut, and the only one on a phone. Everything in the palette is also reachable from the navigation."
30
31
  ],
31
32
  "states": {
32
33
  "loading": {
33
- "must": "Render the shell immediately and load only the content region. Never block the header on the page's data.",
34
+ "must": "Render the shell and the PageHeader immediately and load only what is beneath it. Never block the header on the page's data; when the title itself is data (a record's name), show the route's generic name until it arrives.",
34
35
  "why": "the navigation is what a user reaches for when a page is slow; hiding it makes a slow page feel like a broken one"
35
36
  },
36
37
  "empty": {
@@ -38,7 +39,7 @@
38
39
  "why": "a blank content region with working chrome reads as a failed load"
39
40
  },
40
41
  "error": {
41
- "must": "Keep the shell. Put the error inside <main> with a retry and a way back to somewhere that works.",
42
+ "must": "Keep the shell and the PageHeader. Put the error beneath the header inside <main>, with a retry and a way back to somewhere that works.",
42
43
  "why": "a full-page error strands the user with no navigation, so their only option is the browser's back button"
43
44
  }
44
45
  },
@@ -102,6 +103,14 @@
102
103
  ],
103
104
  "Kbd": [
104
105
  "shortcut"
106
+ ],
107
+ "PageHeader": [
108
+ "title",
109
+ "titleId",
110
+ "description",
111
+ "breadcrumb",
112
+ "status",
113
+ "actions"
105
114
  ]
106
115
  },
107
116
  "variantsUsed": {
@@ -120,7 +129,7 @@
120
129
  "requires": [
121
130
  "`menuLabel` on Header — the mobile toggle is icon-only",
122
131
  "a <nav> with its own accessible name wrapping the NavItems; Header supplies the banner landmark, not the navigation one",
123
- "exactly one <main>, and exactly one h1 inside it",
132
+ "exactly one <main>, and exactly one h1 inside it — the PageHeader's title",
124
133
  "`aria-current=\"page\"` on the NavItem for the current route — colour alone does not tell a screen-reader user where they are",
125
134
  "with a Sidebar, `isCurrent` on the SidebarItem for the current route, and a Sidebar `label` distinct from any other nav on the page"
126
135
  ],
@@ -144,6 +153,10 @@
144
153
  {
145
154
  "dont": "rendering a second nav for mobile",
146
155
  "why": "Header moves the one copy, and two copies duplicate every link in the accessibility tree"
156
+ },
157
+ {
158
+ "dont": "a hand-built title block instead of PageHeader",
159
+ "why": "the demo had five, in three shapes, with actions aligned three ways; PageHeader is the one shape, and the one place its gaps and alignment are decided"
147
160
  }
148
161
  ]
149
162
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "package": "ionbase-ui",
3
- "version": "0.81.1",
3
+ "version": "0.86.0",
4
4
  "usage": "A pattern is a documented composition of components, not a component. Read one here, then read the contracts of what it composes.",
5
5
  "patterns": {
6
6
  "AgentRun": {
@@ -55,7 +55,7 @@
55
55
  "Button",
56
56
  "Badge",
57
57
  "Alert",
58
- "Input",
58
+ "SearchField",
59
59
  "TagGroup"
60
60
  ],
61
61
  "drivenBy": "useTableSort",
@@ -90,6 +90,8 @@
90
90
  "Input",
91
91
  "Select",
92
92
  "Checkbox",
93
+ "CheckboxGroup",
94
+ "Fieldset",
93
95
  "Radio",
94
96
  "RadioGroup",
95
97
  "Toggle",
@@ -137,6 +139,7 @@
137
139
  "Logo",
138
140
  "LogoMark",
139
141
  "Avatar",
142
+ "PageHeader",
140
143
  "Button",
141
144
  "Divider",
142
145
  "ToastProvider",
@@ -0,0 +1,65 @@
1
+ /*
2
+ * Fieldset — and CheckboxGroup and RadioGroup, which render the same shell.
3
+ *
4
+ * The type is Form Field's (`.ion-field`, input.css): the legend is its label,
5
+ * the helper its helper, the error the same recolour. A group of fields reads
6
+ * as one field with several controls, so it must not introduce a second label
7
+ * style for agents and designers to choose between.
8
+ *
9
+ * The fieldset stays `display: block`. A rendered <legend> is laid out in the
10
+ * fieldset's border, not as a flex item, so a flex column here would space
11
+ * everything except the gap under the legend. Spacing is margins on the legend
12
+ * and helper, and a flex wrapper around the fields themselves.
13
+ *
14
+ * Two spacings. A Fieldset of Inputs spaces them as a form does, 16; the
15
+ * choice groups space their options at 8, which is what RadioGroup has always
16
+ * used — options in a list, not fields in a form.
17
+ */
18
+ .ion-fieldset {
19
+ --ion-fieldset-gap: var(--spacing-16);
20
+ --ion-fieldset-inline-gap: var(--spacing-16);
21
+
22
+ min-width: 0; /* a fieldset's default min-content width would stop wrapping */
23
+ margin: 0;
24
+ padding: 0;
25
+ border: none;
26
+ font-family: var(--font-family-sans);
27
+ }
28
+
29
+ .ion-fieldset--choices {
30
+ --ion-fieldset-gap: var(--spacing-8);
31
+ }
32
+
33
+ .ion-fieldset__legend {
34
+ /* Legend has default inline padding; the label beside an Input has none. */
35
+ padding: 0;
36
+ margin-bottom: var(--spacing-6);
37
+ color: var(--text-secondary);
38
+ font-size: var(--type-body-sm);
39
+ line-height: var(--type-body-sm-line-height);
40
+ font-weight: var(--font-weight-medium);
41
+ }
42
+
43
+ .ion-fieldset__content {
44
+ display: flex;
45
+ flex-direction: column;
46
+ gap: var(--ion-fieldset-gap);
47
+ }
48
+
49
+ .ion-fieldset--horizontal .ion-fieldset__content {
50
+ flex-flow: row wrap;
51
+ column-gap: var(--ion-fieldset-inline-gap);
52
+ }
53
+
54
+ .ion-fieldset__helper {
55
+ display: block;
56
+ margin-top: var(--spacing-6);
57
+ color: var(--text-tertiary);
58
+ font-size: var(--type-body-sm);
59
+ line-height: var(--type-body-sm-line-height);
60
+ font-weight: var(--font-weight-regular);
61
+ }
62
+
63
+ .ion-fieldset--error .ion-fieldset__helper {
64
+ color: var(--text-error);
65
+ }
@@ -37,6 +37,7 @@
37
37
  @import url('./select.css');
38
38
  @import url('./checkbox.css');
39
39
  @import url('./radio.css');
40
+ @import url('./fieldset.css');
40
41
  @import url('./toggle.css');
41
42
  @import url('./menu.css');
42
43
  @import url('./avatar.css');
@@ -77,6 +78,7 @@
77
78
  @import url('./prompt-input.css');
78
79
  @import url('./tool-call.css');
79
80
  @import url('./number-input.css');
81
+ @import url('./search-field.css');
80
82
  @import url('./segmented-control.css');
81
83
  @import url('./sidebar.css');
82
84
  @import url('./file-upload.css');
@@ -95,6 +97,7 @@
95
97
  @import url('./setting-row.css');
96
98
  @import url('./chart.css');
97
99
  @import url('./card.css');
100
+ @import url('./page-header.css');
98
101
  @import url('./tag-group.css');
99
102
  @import url('./kbd.css');
100
103
  @import url('./command-palette.css');