@editora/ui-core 0.1.24 → 0.2.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.
- package/README.md +339 -5
- package/dist/accordion.cjs.js +13 -12
- package/dist/accordion.esm.js +13 -12
- package/dist/alert-dialog.cjs.js +76 -45
- package/dist/alert-dialog.esm.js +179 -135
- package/dist/alert.cjs.js +41 -32
- package/dist/alert.esm.js +79 -70
- package/dist/animated-beam.cjs.js +42 -50
- package/dist/animated-beam.esm.js +47 -55
- package/dist/animated-list.cjs.js +11 -27
- package/dist/animated-list.esm.js +12 -28
- package/dist/animated-text.cjs.js +4 -4
- package/dist/animated-text.esm.js +4 -4
- package/dist/app-header.cjs.js +5 -5
- package/dist/app-header.esm.js +6 -6
- package/dist/aspect-ratio.cjs.js +10 -12
- package/dist/aspect-ratio.esm.js +11 -13
- package/dist/avatar.cjs.js +13 -17
- package/dist/avatar.esm.js +13 -17
- package/dist/badge.cjs.js +27 -22
- package/dist/badge.esm.js +32 -27
- package/dist/block-controls.cjs.js +11 -12
- package/dist/block-controls.esm.js +8 -9
- package/dist/box.cjs.js +2 -3
- package/dist/box.esm.js +2 -3
- package/dist/breadcrumb.cjs.js +12 -18
- package/dist/breadcrumb.esm.js +11 -17
- package/dist/button.cjs.js +1 -1
- package/dist/button.esm.js +1 -1
- package/dist/{calendar-B3PUKHQm.mjs → calendar-DmxiZrR7.mjs} +126 -117
- package/dist/{calendar-D-mXMgqc.js → calendar-o273O28D.js} +53 -44
- package/dist/calendar.cjs.js +1 -1
- package/dist/calendar.esm.js +1 -1
- package/dist/card.cjs.js +6 -7
- package/dist/card.esm.js +5 -6
- package/dist/chart.cjs.js +52 -52
- package/dist/chart.esm.js +95 -95
- package/dist/checkbox.cjs.js +19 -15
- package/dist/checkbox.esm.js +19 -15
- package/dist/collapsible.cjs.js +7 -11
- package/dist/collapsible.esm.js +7 -11
- package/dist/color-picker.cjs.js +36 -17
- package/dist/color-picker.esm.js +132 -113
- package/dist/combobox.cjs.js +57 -54
- package/dist/combobox.esm.js +62 -58
- package/dist/command-palette.cjs.js +1 -0
- package/dist/command-palette.esm.js +1 -0
- package/dist/command.cjs.js +32 -14
- package/dist/command.esm.js +46 -28
- package/dist/components/date-time-utils.d.ts.map +1 -1
- package/dist/components/gantt-schedule.d.ts +79 -0
- package/dist/components/gantt-schedule.d.ts.map +1 -0
- package/dist/components/ui-accordion.d.ts.map +1 -1
- package/dist/components/ui-alert-dialog.d.ts +2 -0
- package/dist/components/ui-alert-dialog.d.ts.map +1 -1
- package/dist/components/ui-alert.d.ts.map +1 -1
- package/dist/components/ui-animated-beam.d.ts.map +1 -1
- package/dist/components/ui-animated-list.d.ts.map +1 -1
- package/dist/components/ui-aspect-ratio.d.ts.map +1 -1
- package/dist/components/ui-avatar.d.ts.map +1 -1
- package/dist/components/ui-badge.d.ts.map +1 -1
- package/dist/components/ui-block-controls.d.ts.map +1 -1
- package/dist/components/ui-box.d.ts.map +1 -1
- package/dist/components/ui-breadcrumb.d.ts.map +1 -1
- package/dist/components/ui-button.d.ts.map +1 -1
- package/dist/components/ui-calendar.d.ts.map +1 -1
- package/dist/components/ui-card.d.ts.map +1 -1
- package/dist/components/ui-checkbox.d.ts.map +1 -1
- package/dist/components/ui-collapsible.d.ts.map +1 -1
- package/dist/components/ui-color-picker.d.ts.map +1 -1
- package/dist/components/ui-combobox.d.ts.map +1 -1
- package/dist/components/ui-command-palette.d.ts.map +1 -1
- package/dist/components/ui-command.d.ts.map +1 -1
- package/dist/components/ui-container.d.ts.map +1 -1
- package/dist/components/ui-context-menu.d.ts.map +1 -1
- package/dist/components/ui-data-table.d.ts +7 -0
- package/dist/components/ui-data-table.d.ts.map +1 -1
- package/dist/components/ui-date-picker.d.ts.map +1 -1
- package/dist/components/ui-date-range-picker.d.ts.map +1 -1
- package/dist/components/ui-date-range-time-picker.d.ts.map +1 -1
- package/dist/components/ui-date-time-picker.d.ts.map +1 -1
- package/dist/components/ui-dialog.d.ts +2 -0
- package/dist/components/ui-dialog.d.ts.map +1 -1
- package/dist/components/ui-dock.d.ts.map +1 -1
- package/dist/components/ui-drawer.d.ts.map +1 -1
- package/dist/components/ui-dropdown.d.ts.map +1 -1
- package/dist/components/ui-empty-state.d.ts.map +1 -1
- package/dist/components/ui-field.d.ts.map +1 -1
- package/dist/components/ui-fieldset.d.ts.map +1 -1
- package/dist/components/ui-file-upload.d.ts.map +1 -1
- package/dist/components/ui-floating-toolbar.d.ts.map +1 -1
- package/dist/components/ui-form.d.ts.map +1 -1
- package/dist/components/ui-gantt.d.ts +186 -2
- package/dist/components/ui-gantt.d.ts.map +1 -1
- package/dist/components/ui-icon-cloud.d.ts.map +1 -1
- package/dist/components/ui-inline-edit.d.ts.map +1 -1
- package/dist/components/ui-input.d.ts.map +1 -1
- package/dist/components/ui-marquee.d.ts.map +1 -1
- package/dist/components/ui-menu.d.ts.map +1 -1
- package/dist/components/ui-menubar.d.ts.map +1 -1
- package/dist/components/ui-meter.d.ts.map +1 -1
- package/dist/components/ui-multi-select.d.ts.map +1 -1
- package/dist/components/ui-number-field.d.ts.map +1 -1
- package/dist/components/ui-orbiter.d.ts.map +1 -1
- package/dist/components/ui-pagination.d.ts.map +1 -1
- package/dist/components/ui-password-field.d.ts.map +1 -1
- package/dist/components/ui-pin-input.d.ts.map +1 -1
- package/dist/components/ui-popover.d.ts.map +1 -1
- package/dist/components/ui-progress.d.ts.map +1 -1
- package/dist/components/ui-radio-group.d.ts.map +1 -1
- package/dist/components/ui-radio.d.ts.map +1 -1
- package/dist/components/ui-rating.d.ts +1 -0
- package/dist/components/ui-rating.d.ts.map +1 -1
- package/dist/components/ui-scroll-area.d.ts.map +1 -1
- package/dist/components/ui-section.d.ts.map +1 -1
- package/dist/components/ui-select.d.ts.map +1 -1
- package/dist/components/ui-selection-popup.d.ts.map +1 -1
- package/dist/components/ui-slider.d.ts.map +1 -1
- package/dist/components/ui-sortable.d.ts.map +1 -1
- package/dist/components/ui-spinning-text.d.ts.map +1 -1
- package/dist/components/ui-split-button.d.ts.map +1 -1
- package/dist/components/ui-splitter.d.ts.map +1 -1
- package/dist/components/ui-stepper.d.ts.map +1 -1
- package/dist/components/ui-switch.d.ts.map +1 -1
- package/dist/components/ui-tabs.d.ts.map +1 -1
- package/dist/components/ui-tags-input.d.ts.map +1 -1
- package/dist/components/ui-textarea.d.ts.map +1 -1
- package/dist/components/ui-time-picker.d.ts.map +1 -1
- package/dist/components/ui-toggle-group.d.ts +2 -0
- package/dist/components/ui-toggle-group.d.ts.map +1 -1
- package/dist/components/ui-toggle.d.ts.map +1 -1
- package/dist/components/ui-toolbar.d.ts +2 -0
- package/dist/components/ui-toolbar.d.ts.map +1 -1
- package/dist/components/ui-tooltip.d.ts.map +1 -1
- package/dist/components/ui-transfer-list.d.ts.map +1 -1
- package/dist/components/ui-tree-item.d.ts.map +1 -1
- package/dist/components/ui-tree.d.ts.map +1 -1
- package/dist/components/ui-wizard.d.ts.map +1 -1
- package/dist/container.cjs.js +6 -12
- package/dist/container.esm.js +8 -14
- package/dist/context-menu.cjs.js +8 -8
- package/dist/context-menu.esm.js +42 -41
- package/dist/data-table.cjs.js +18 -15
- package/dist/data-table.esm.js +207 -187
- package/dist/date-field.cjs.js +8 -8
- package/dist/date-field.esm.js +7 -7
- package/dist/date-picker.cjs.js +27 -18
- package/dist/date-picker.esm.js +57 -48
- package/dist/date-range-picker.cjs.js +22 -17
- package/dist/date-range-picker.esm.js +31 -26
- package/dist/date-range-time-picker.cjs.js +26 -19
- package/dist/date-range-time-picker.esm.js +23 -16
- package/dist/date-time-picker.cjs.js +23 -16
- package/dist/date-time-picker.esm.js +88 -81
- package/dist/{date-time-utils-BTlxnz5j.mjs → date-time-utils-B4hAkt36.mjs} +75 -68
- package/dist/date-time-utils-DdigV4hs.js +1 -0
- package/dist/dialog.cjs.js +57 -41
- package/dist/dialog.esm.js +84 -51
- package/dist/dock.cjs.js +16 -30
- package/dist/dock.esm.js +26 -40
- package/dist/drawer.cjs.js +8 -12
- package/dist/drawer.esm.js +6 -10
- package/dist/dropdown.cjs.js +8 -6
- package/dist/dropdown.esm.js +33 -30
- package/dist/empty-state.cjs.js +17 -15
- package/dist/empty-state.esm.js +13 -11
- package/dist/field.cjs.js +22 -13
- package/dist/field.esm.js +54 -45
- package/dist/fieldset.cjs.js +18 -11
- package/dist/fieldset.esm.js +20 -13
- package/dist/file-upload.cjs.js +77 -35
- package/dist/file-upload.esm.js +152 -110
- package/dist/floating-toolbar.cjs.js +6 -7
- package/dist/floating-toolbar.esm.js +8 -9
- package/dist/form.cjs.js +20 -23
- package/dist/form.esm.js +20 -23
- package/dist/gantt.cjs.js +525 -110
- package/dist/gantt.esm.js +1882 -377
- package/dist/hover-card.cjs.js +7 -7
- package/dist/hover-card.esm.js +7 -7
- package/dist/icon-cloud.cjs.js +19 -36
- package/dist/icon-cloud.esm.js +41 -58
- package/dist/index.cjs.js +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +108 -104
- package/dist/inline-edit.cjs.js +47 -19
- package/dist/inline-edit.esm.js +66 -38
- package/dist/input.cjs.js +44 -37
- package/dist/input.esm.js +59 -52
- package/dist/layout.cjs.js +3 -3
- package/dist/layout.esm.js +3 -3
- package/dist/marquee.cjs.js +7 -10
- package/dist/marquee.esm.js +7 -10
- package/dist/menu.cjs.js +8 -24
- package/dist/menu.esm.js +52 -72
- package/dist/menubar.cjs.js +9 -31
- package/dist/menubar.esm.js +127 -153
- package/dist/meter.cjs.js +4 -9
- package/dist/meter.esm.js +6 -11
- package/dist/multi-select.cjs.js +48 -35
- package/dist/multi-select.esm.js +67 -53
- package/dist/navigation-menu.cjs.js +10 -10
- package/dist/navigation-menu.esm.js +33 -33
- package/dist/number-field.cjs.js +27 -16
- package/dist/number-field.esm.js +36 -25
- package/dist/odometer.cjs.js +5 -5
- package/dist/odometer.esm.js +3 -3
- package/dist/orbiter.cjs.js +11 -28
- package/dist/orbiter.esm.js +28 -45
- package/dist/overlay-motion-B56x1GoY.js +49 -0
- package/dist/overlay-motion-BX3dPLay.mjs +120 -0
- package/dist/pagination.cjs.js +28 -25
- package/dist/pagination.esm.js +54 -51
- package/dist/password-field.cjs.js +38 -33
- package/dist/password-field.esm.js +62 -57
- package/dist/pin-input.cjs.js +17 -13
- package/dist/pin-input.esm.js +23 -19
- package/dist/plugin-panel.cjs.js +1 -1
- package/dist/plugin-panel.esm.js +1 -1
- package/dist/popover.cjs.js +16 -28
- package/dist/popover.esm.js +29 -45
- package/dist/portal-DeaM1tYY.mjs +121 -0
- package/dist/portal-XbYR3m_q.js +1 -0
- package/dist/portal.d.ts +3 -1
- package/dist/portal.d.ts.map +1 -1
- package/dist/{positioner-D0VGxtYU.mjs → positioner-BE8Nbho2.mjs} +5 -3
- package/dist/{positioner-D_fqyx_j.js → positioner-DZ1FW6A9.js} +1 -1
- package/dist/positioner.cjs.js +1 -1
- package/dist/positioner.esm.js +1 -1
- package/dist/primitives/overlay-motion.d.ts +47 -0
- package/dist/primitives/overlay-motion.d.ts.map +1 -0
- package/dist/primitives/positioner.d.ts.map +1 -1
- package/dist/progress.cjs.js +11 -16
- package/dist/progress.esm.js +37 -42
- package/dist/quick-actions.cjs.js +13 -13
- package/dist/quick-actions.esm.js +11 -11
- package/dist/radio-group.cjs.js +50 -26
- package/dist/radio-group.esm.js +53 -29
- package/dist/radio.cjs.js +15 -12
- package/dist/radio.esm.js +15 -12
- package/dist/rating.cjs.js +11 -15
- package/dist/rating.esm.js +48 -50
- package/dist/{runtime-CFnK53iC.mjs → runtime-CQM6wZOc.mjs} +498 -514
- package/dist/runtime-DxCl0A5q.js +5 -0
- package/dist/runtime.cjs.js +1 -1
- package/dist/runtime.d.ts +3 -2
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.esm.js +36 -32
- package/dist/scroll-area.cjs.js +3 -4
- package/dist/scroll-area.esm.js +3 -4
- package/dist/section.cjs.js +2 -4
- package/dist/section.esm.js +2 -4
- package/dist/select.cjs.js +40 -73
- package/dist/select.esm.js +55 -87
- package/dist/selection-popup.cjs.js +3 -4
- package/dist/selection-popup.esm.js +3 -4
- package/dist/semantic-tokens.d.ts +17 -0
- package/dist/semantic-tokens.d.ts.map +1 -0
- package/dist/sidebar.cjs.js +22 -22
- package/dist/sidebar.esm.js +25 -25
- package/dist/skeleton.cjs.js +2 -2
- package/dist/skeleton.esm.js +2 -2
- package/dist/slider.cjs.js +22 -26
- package/dist/slider.esm.js +25 -29
- package/dist/sortable.cjs.js +4 -5
- package/dist/sortable.esm.js +4 -5
- package/dist/spinning-text.cjs.js +4 -13
- package/dist/spinning-text.esm.js +4 -13
- package/dist/split-button.cjs.js +5 -5
- package/dist/split-button.esm.js +15 -14
- package/dist/splitter.cjs.js +52 -10
- package/dist/splitter.esm.js +55 -13
- package/dist/stepper.cjs.js +31 -65
- package/dist/stepper.esm.js +32 -66
- package/dist/switch.cjs.js +20 -22
- package/dist/switch.esm.js +20 -22
- package/dist/table.cjs.js +5 -5
- package/dist/table.esm.js +20 -20
- package/dist/tabs.cjs.js +91 -21
- package/dist/tabs.esm.js +182 -112
- package/dist/tags-input.cjs.js +41 -15
- package/dist/tags-input.esm.js +73 -47
- package/dist/textarea.cjs.js +32 -33
- package/dist/textarea.esm.js +38 -39
- package/dist/theme.d.ts +25 -1
- package/dist/theme.d.ts.map +1 -1
- package/dist/time-field.cjs.js +7 -7
- package/dist/time-field.esm.js +6 -6
- package/dist/time-picker.cjs.js +16 -13
- package/dist/time-picker.esm.js +27 -24
- package/dist/timeline.cjs.js +10 -10
- package/dist/timeline.esm.js +7 -7
- package/dist/toggle-group.cjs.js +13 -13
- package/dist/toggle-group.esm.js +66 -61
- package/dist/toggle.cjs.js +52 -34
- package/dist/toggle.esm.js +80 -62
- package/dist/toolbar.cjs.js +14 -14
- package/dist/toolbar.esm.js +41 -33
- package/dist/tooltip.cjs.js +3 -3
- package/dist/tooltip.esm.js +39 -33
- package/dist/transfer-list.cjs.js +28 -29
- package/dist/transfer-list.esm.js +28 -29
- package/dist/{tree-B_oQput6.mjs → tree-33fVNnaf.mjs} +6 -5
- package/dist/{tree-SivHxcAy.js → tree-Dc02MChE.js} +6 -5
- package/dist/tree-item.cjs.js +9 -8
- package/dist/tree-item.esm.js +13 -12
- package/dist/tree.cjs.js +1 -1
- package/dist/tree.esm.js +1 -1
- package/dist/{ui-button-Co8Sid6t.mjs → ui-button-C3OmI7Sn.mjs} +152 -154
- package/dist/{ui-button-BPrzJScZ.js → ui-button-CnLwXBnx.js} +107 -109
- package/dist/wizard.cjs.js +39 -36
- package/dist/wizard.esm.js +39 -36
- package/package.json +1 -1
- package/dist/date-time-utils-y3AvNvGe.js +0 -1
- package/dist/portal-DgpQ3Jo1.js +0 -1
- package/dist/portal-bR42gHvG.mjs +0 -118
- package/dist/runtime-DwE-tizc.js +0 -1
package/README.md
CHANGED
|
@@ -252,11 +252,218 @@ and resize, and a toolbar for zoom, filter and sort. Give it `tasks` and `links`
|
|
|
252
252
|
<img src="https://raw.githubusercontent.com/ajaykr089/Editora/main/packages/ui-core/docs/images/gantt.png" alt="A Gantt chart with a task bar for API contracts, a baseline under it, and an arrow to the QA sign-off milestone" width="900">
|
|
253
253
|
</p>
|
|
254
254
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
255
|
+
That is the whole setup for a basic chart. The rest of this section builds on it.
|
|
256
|
+
|
|
257
|
+
### A full planner
|
|
258
|
+
|
|
259
|
+
This one turns on most of the features at once: a two-level time header, weekends and a holiday shaded, parents that
|
|
260
|
+
follow their children, scheduling that pushes the tasks after one you move, the critical path, dependencies you draw
|
|
261
|
+
by dragging, and a date the host refuses to let slip. The chart draws what it is given and reports what the user does;
|
|
262
|
+
the plan lives in your code, so every edit arrives as an event and you decide whether to keep it.
|
|
263
|
+
|
|
264
|
+
```html
|
|
265
|
+
<ui-gantt
|
|
266
|
+
id="planner"
|
|
267
|
+
zoom="week"
|
|
268
|
+
week-start="1"
|
|
269
|
+
bar-variant="soft"
|
|
270
|
+
columns='["label", "assignee", "start", "end", "progress"]'
|
|
271
|
+
non-working-days
|
|
272
|
+
auto-summary
|
|
273
|
+
cascade
|
|
274
|
+
schedule="auto"
|
|
275
|
+
critical-path
|
|
276
|
+
linkable
|
|
277
|
+
creatable
|
|
278
|
+
></ui-gantt>
|
|
279
|
+
|
|
280
|
+
<script type="module">
|
|
281
|
+
import '@editora/ui-core';
|
|
282
|
+
|
|
283
|
+
const planner = document.getElementById('planner');
|
|
284
|
+
const day = (offset) => {
|
|
285
|
+
const date = new Date();
|
|
286
|
+
date.setHours(0, 0, 0, 0);
|
|
287
|
+
date.setDate(date.getDate() + offset);
|
|
288
|
+
return date;
|
|
289
|
+
};
|
|
290
|
+
|
|
291
|
+
// The chart draws what it is given and reports what the user does; the plan lives here.
|
|
292
|
+
let tasks = [
|
|
293
|
+
{ id: 'discovery', label: 'Discovery', type: 'summary' },
|
|
294
|
+
{ id: 'research', label: 'User research', parent: 'discovery', start: day(-21), end: day(-12), progress: 100, assignee: 'Mina', baselineStart: day(-21), baselineEnd: day(-13) },
|
|
295
|
+
{ id: 'interviews', label: 'Interviews', parent: 'discovery', start: day(-12), end: day(-5), progress: 100, assignee: 'Jonas' },
|
|
296
|
+
{ id: 'scope', label: 'Scope signed off', parent: 'discovery', start: day(-5), type: 'milestone', tone: 'success' },
|
|
297
|
+
{ id: 'build', label: 'Build', type: 'summary' },
|
|
298
|
+
{ id: 'api', label: 'API and data model', parent: 'build', start: day(-4), end: day(10), progress: 70, assignee: 'Priya' },
|
|
299
|
+
{
|
|
300
|
+
id: 'ui',
|
|
301
|
+
label: 'Planner UI',
|
|
302
|
+
parent: 'build',
|
|
303
|
+
start: day(-2),
|
|
304
|
+
end: day(18),
|
|
305
|
+
progress: 45,
|
|
306
|
+
assignee: 'Tomás',
|
|
307
|
+
segments: [{ start: day(-2), end: day(5) }, { start: day(8), end: day(18) }]
|
|
308
|
+
},
|
|
309
|
+
{ id: 'integration', label: 'Integration', parent: 'build', start: day(18), end: day(26), progress: 0, assignee: 'Priya' },
|
|
310
|
+
{ id: 'launch', label: 'Launch', type: 'summary' },
|
|
311
|
+
{ id: 'qa', label: 'QA and fixes', parent: 'launch', start: day(26), end: day(33), assignee: 'Aiko' },
|
|
312
|
+
{ id: 'beta', label: 'Beta', parent: 'launch', start: day(33), end: day(40), assignee: 'Aiko' },
|
|
313
|
+
{ id: 'release', label: 'Release', parent: 'launch', start: day(40), type: 'milestone', tone: 'danger' },
|
|
314
|
+
{ id: 'docs', label: 'Write the docs', start: day(30), end: day(38), progress: 20, assignee: 'Sam' }
|
|
315
|
+
];
|
|
316
|
+
let links = [
|
|
317
|
+
{ id: 'l1', source: 'research', target: 'interviews' },
|
|
318
|
+
{ id: 'l2', source: 'interviews', target: 'scope' },
|
|
319
|
+
{ id: 'l3', source: 'scope', target: 'api', lag: 1 },
|
|
320
|
+
{ id: 'l4', source: 'scope', target: 'ui', type: 's2s', lag: 3 },
|
|
321
|
+
{ id: 'l5', source: 'api', target: 'integration' },
|
|
322
|
+
{ id: 'l6', source: 'ui', target: 'integration' },
|
|
323
|
+
{ id: 'l7', source: 'integration', target: 'qa' },
|
|
324
|
+
{ id: 'l8', source: 'qa', target: 'beta' },
|
|
325
|
+
{ id: 'l9', source: 'beta', target: 'release' },
|
|
326
|
+
{ id: 'l10', source: 'beta', target: 'docs' } // docs are planned before beta ends: drawn red
|
|
327
|
+
];
|
|
328
|
+
const sync = () => {
|
|
329
|
+
planner.tasks = tasks;
|
|
330
|
+
planner.links = links;
|
|
331
|
+
};
|
|
332
|
+
planner.holidays = [{ date: day(12), label: 'Founders day' }];
|
|
333
|
+
const patch = (id, changes) => {
|
|
334
|
+
tasks = tasks.map((task) => (task.id === id ? { ...task, ...changes } : task));
|
|
335
|
+
};
|
|
336
|
+
sync();
|
|
337
|
+
|
|
338
|
+
// Keep the release date: refuse any change that would push it.
|
|
339
|
+
planner.addEventListener('beforetaskchange', (event) => {
|
|
340
|
+
if (event.detail.affected.some((change) => change.id === 'release')) event.preventDefault();
|
|
341
|
+
});
|
|
342
|
+
planner.addEventListener('taskchange', ({ detail }) => {
|
|
343
|
+
patch(detail.id, { start: detail.start, end: detail.end });
|
|
344
|
+
sync();
|
|
345
|
+
});
|
|
346
|
+
planner.addEventListener('taskrename', ({ detail }) => {
|
|
347
|
+
patch(detail.id, { label: detail.label });
|
|
348
|
+
sync();
|
|
349
|
+
});
|
|
350
|
+
planner.addEventListener('taskcreate', ({ detail }) => {
|
|
351
|
+
const id = `task-${tasks.length + 1}`;
|
|
352
|
+
tasks = [...tasks, { id, label: 'New task', start: detail.start, end: detail.end, parent: detail.parent }];
|
|
353
|
+
sync();
|
|
354
|
+
planner.scrollToTask(id);
|
|
355
|
+
});
|
|
356
|
+
planner.addEventListener('linkcreate', ({ detail }) => {
|
|
357
|
+
links = [...links, { id: `l${links.length + 1}`, ...detail }];
|
|
358
|
+
sync();
|
|
359
|
+
});
|
|
360
|
+
planner.addEventListener('linkdelete', ({ detail }) => {
|
|
361
|
+
links = links.filter((link) => link.id !== detail.id);
|
|
362
|
+
sync();
|
|
363
|
+
});
|
|
364
|
+
</script>
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
<p align="center">
|
|
368
|
+
<img src="https://raw.githubusercontent.com/ajaykr089/Editora/main/packages/ui-core/docs/images/gantt-planner.png" alt="A project planner: three summary rows, red critical-path bars joined by dependency arrows, shaded weekends and a holiday, a Today marker, a red dashed link for a task planned before its predecessor ends, and a tooltip on the Beta bar" width="900">
|
|
369
|
+
</p>
|
|
370
|
+
|
|
371
|
+
The red bars are the critical path (`critical-path`), the red dashed arrow is a dependency that is already broken
|
|
372
|
+
(Write the docs is planned before Beta ends), the grey strip under User research is its baseline, and the dots on
|
|
373
|
+
Beta are the handles `linkable` adds.
|
|
374
|
+
|
|
375
|
+
### Timeline and display
|
|
376
|
+
|
|
377
|
+
- `zoom`: `day`, `week`, `month`, `quarter`, `year` or `fit` (the whole project scaled to the chart's width, re-fitted when it is
|
|
378
|
+
resized). The time header has two rows (month over days or weeks, year over months or quarters), a pill marks today, and the chart
|
|
379
|
+
opens on today when it is off the first screen (`initial-scroll="start"` keeps the start).
|
|
380
|
+
- `week-start` (`0` is Sunday) sets the first day of the week; it defaults to the locale's.
|
|
381
|
+
- `bar-variant`: `solid`, `soft`, `striped`, `outline` or `glass`. Progress is drawn inside each bar, and a task with `segments` is drawn in parts,
|
|
382
|
+
each with its own progress. `sort`: `none`, `start`, `end`, `label` or `progress`.
|
|
383
|
+
- Non-working time: `non-working-days` (the attribute alone means the weekend, or `0,6` / `[1,2]`) and `holidays` (`["2026-12-25", {"date": "2026-12-26", "label": "Boxing Day"}]`)
|
|
384
|
+
shade those days behind the rows (not at month scales and wider, where a day is a few pixels) and mute them in the day header. They are shown, not scheduled
|
|
385
|
+
around: task lengths are calendar days.
|
|
386
|
+
- Size: by default the chart grows with its rows up to 620px (`max-height="60vh"` or the `--ui-gantt-max-height` variable change that); add
|
|
387
|
+
`fill` and give the element a height (or a flex/grid cell) and it fills it, with the rows scrolling inside. Below 640px of width only the
|
|
388
|
+
name column is kept. Large task sets (over 240 rows) are virtualized automatically; `virtualized="false"` turns that off.
|
|
389
|
+
- Dates are calendar days (`YYYY-MM-DD`). A time or offset after the day (`2026-03-02T23:30:00Z`) is ignored, so a task never moves a
|
|
390
|
+
day with the viewer's time zone; `taskchange` reports plain `YYYY-MM-DD`.
|
|
391
|
+
- Translate every word with `labels` (a JSON object with any subset of the label keys, e.g. `{"title": "Planning", "zoomWeek": "semaine"}`) and
|
|
392
|
+
set `locale` (`fr-FR`) for month names, date formats and the first day of the week.
|
|
393
|
+
|
|
394
|
+
### Task list
|
|
395
|
+
|
|
396
|
+
- Choose the columns with `columns` (`["label", "assignee", "start", "end", "duration", "progress"]`, or objects with a `label` and a
|
|
397
|
+
`width`) and size the list with `grid-width`; a splitter on its edge resizes it (mouse, touch, or the arrow keys) and fires `gridresize`.
|
|
398
|
+
- Parents: opening or closing a branch fires `tasktoggle`. `auto-summary` makes a parent span its children and take their progress (weighted by length)
|
|
399
|
+
when it has none; `cascade` lets you move a parent and everything under it together (`beforetaskchange` lists the tasks it moves in `affected`,
|
|
400
|
+
`taskchange` fires for each).
|
|
401
|
+
|
|
402
|
+
### Dependencies and scheduling
|
|
403
|
+
|
|
404
|
+
- A link may carry a `lag` (days) and its `type` says what it ties: `e2s` (the default), `s2s`, `e2e` or `s2e`. A link whose target is too early is
|
|
405
|
+
drawn red and dashed.
|
|
406
|
+
- `schedule="auto"` also pushes the tasks that follow a task you move (later only, keeping their length, down the chain, as one change you can
|
|
407
|
+
refuse in `beforetaskchange`); `schedule="off"` turns both off. The pushing counts calendar days.
|
|
408
|
+
- `critical-path` computes the critical path from the links (no slack on a chain that is tight all the way) and draws those bars as critical, on top of any
|
|
409
|
+
task you flag `critical`.
|
|
410
|
+
- `linkable` shows dots beside each bar: drag one onto another bar and the chart fires `linkcreate` with the source, the target and the type the two ends
|
|
411
|
+
give (`e2s`, `s2s`, `e2e`, `s2e`); click a link to select it and press Delete to get `linkdelete`. As with tasks, your code owns the data.
|
|
412
|
+
|
|
413
|
+
### Editing
|
|
414
|
+
|
|
415
|
+
- Dragging: a bar can be dragged, resized from its ends, or moved with the arrow keys (Shift extends the end). The chart scrolls when a drag is held
|
|
416
|
+
near the left or right edge, Escape cancels it, and `snap="week"` or `snap="month"` snaps it to whole weeks or months. `beforetaskchange`
|
|
417
|
+
(cancelable) fires before the dates change, so a host can refuse the change with `event.preventDefault()`; `taskchange` fires after.
|
|
418
|
+
- Rename in place: double-click a task's name (or press F2 on a row or a bar). Enter or leaving the field keeps it and fires `taskrename`
|
|
419
|
+
(cancelable), Escape drops it.
|
|
420
|
+
- With `creatable` there is a **+ Add task** button, and a double-click on empty timeline space does the same for that
|
|
421
|
+
day: the chart fires `taskcreate` with the dates and the neighbour and your code adds the task. Nothing is written to your data by the chart.
|
|
422
|
+
- `readonly` turns all of this off and keeps the browsing.
|
|
423
|
+
|
|
424
|
+
### Keyboard and accessibility
|
|
425
|
+
|
|
426
|
+
- Tab enters the task list once (a row) and once more for the bars. On a row, Up/Down, Home/End and PageUp/PageDown move between rows, Right
|
|
427
|
+
opens a branch or steps into it, Left closes it or climbs to the parent, Enter or Space selects. On a bar the same keys move between rows, and
|
|
428
|
+
Left/Right move the bar a day (Shift: extend the end), Delete asks to remove it, and Escape closes the tooltip.
|
|
429
|
+
- Each bar is named for assistive technology with its dates, progress, owner and critical flag, and shows the same facts in a tooltip on
|
|
430
|
+
hover or keyboard focus. While you drag a bar, the tooltip shows the dates it would take. Bars and the touch targets of the splitter and the
|
|
431
|
+
link handles grow on touch screens.
|
|
432
|
+
|
|
433
|
+
### Export and print
|
|
434
|
+
|
|
435
|
+
`exportSvg()` returns the whole chart (not just the part on screen) as a standalone SVG string, and the chart prints as a whole (no scroll
|
|
436
|
+
area, no sticky headers, no controls; use `zoom="fit"` for a wide project).
|
|
437
|
+
|
|
438
|
+
### Reference
|
|
439
|
+
|
|
440
|
+
| Attribute | Values |
|
|
441
|
+
| --- | --- |
|
|
442
|
+
| `zoom` | `day`, `week` (default), `month`, `quarter`, `year`, `fit` |
|
|
443
|
+
| `week-start`, `locale`, `labels` | first weekday (`0`-`6`), a locale tag, a JSON object of label overrides |
|
|
444
|
+
| `bar-variant`, `sort`, `variant` | bar skin, sort key, `contrast` for a dark surface |
|
|
445
|
+
| `columns`, `grid-width` | task list columns and width |
|
|
446
|
+
| `fill`, `max-height`, `virtualized` | sizing and row virtualization |
|
|
447
|
+
| `non-working-days`, `holidays` | shaded days: weekdays, dates |
|
|
448
|
+
| `auto-summary`, `cascade` | parents follow their children, parents move their children |
|
|
449
|
+
| `schedule`, `critical-path` | `auto` pushes successors, red critical bars |
|
|
450
|
+
| `linkable`, `creatable`, `readonly`, `snap`, `initial-scroll` | editing and scrolling behaviour |
|
|
451
|
+
| `filter`, `show-toolbar`, `show-today`, `headless` | toolbar |
|
|
452
|
+
|
|
453
|
+
| Event | `detail` |
|
|
454
|
+
| --- | --- |
|
|
455
|
+
| `beforetaskchange` (cancelable) | `{ id, start, end, previousStart, previousEnd, source, affected }`, `affected` lists the other tasks the change moves in the same shape |
|
|
456
|
+
| `taskchange` | `{ id, start, end }`, once for each task that moved |
|
|
457
|
+
| `taskselect`, `taskdelete` | `{ id }` |
|
|
458
|
+
| `tasktoggle` | `{ id, open }` |
|
|
459
|
+
| `taskrename` (cancelable) | `{ id, label, previousLabel }` |
|
|
460
|
+
| `taskcreate` | `{ start, end, parent, after }` |
|
|
461
|
+
| `linkcreate` | `{ source, target, type }` |
|
|
462
|
+
| `linkselect`, `linkdelete` | `{ id, source, target, type }` |
|
|
463
|
+
| `zoomchange`, `sortchange`, `filterchange`, `gridresize` | `{ zoom }`, `{ sort }`, `{ filter }`, `{ width }` |
|
|
464
|
+
|
|
465
|
+
Methods: `scrollToDate(date)`, `scrollToTask(id)`, `toggleTask(id, open?)`, `expandAll()`, `collapseAll()` and `exportSvg()`. `tasks`, `links`
|
|
466
|
+
and `holidays` are also properties that take arrays (with `Date`s if you like).
|
|
260
467
|
|
|
261
468
|
## Promise dialogs
|
|
262
469
|
|
|
@@ -334,6 +541,130 @@ argument:
|
|
|
334
541
|
Apply the theme early, before the first render. To theme one part of the page, call
|
|
335
542
|
`applyTheme(tokens, element)`.
|
|
336
543
|
|
|
544
|
+
### Follow the system light/dark setting
|
|
545
|
+
|
|
546
|
+
```js
|
|
547
|
+
import { applySystemTheme } from '@editora/ui-core';
|
|
548
|
+
|
|
549
|
+
const stop = applySystemTheme({ accentPalette: 'blue' }); // stop() ends following the system
|
|
550
|
+
```
|
|
551
|
+
|
|
552
|
+
It applies the light or dark theme to match the operating system and switches live when the person changes it. The
|
|
553
|
+
mode is also written as `data-ui-mode="light|dark"` and `color-scheme` on the page, so your own CSS can follow it.
|
|
554
|
+
`light` and `dark` take token overrides for each mode.
|
|
555
|
+
|
|
556
|
+
### As a stylesheet (server rendering)
|
|
557
|
+
|
|
558
|
+
`themeToCss(tokens, ':root')` returns the same variables as CSS text, to put in a `<style>` tag or a `.css` file so the
|
|
559
|
+
first paint is themed without JavaScript. `themeToVariables(tokens)` returns them as a `{ name: value }` object.
|
|
560
|
+
|
|
561
|
+
### Tokens to build on
|
|
562
|
+
|
|
563
|
+
Every value below follows the accent palette, the gray scale and light/dark mode, so custom components that read them
|
|
564
|
+
stay on theme.
|
|
565
|
+
|
|
566
|
+
| Tokens | Meaning |
|
|
567
|
+
| --- | --- |
|
|
568
|
+
| `--ui-color-fill`, `-fill-hover`, `-fill-active` | resting, hover and pressed fill of a neutral control |
|
|
569
|
+
| `--ui-color-line-subtle`, `-line`, `-line-strong` | borders and separators, from quiet to strong |
|
|
570
|
+
| `--ui-color-text-secondary`, `-text-strong` | secondary and primary text |
|
|
571
|
+
| `--ui-color-accent-subtle`, `-accent-fill`, `-accent-fill-hover`, `-accent-fill-active` | tinted accent backgrounds |
|
|
572
|
+
| `--ui-color-accent-line`, `-accent-solid`, `-accent-solid-hover`, `-accent-text` | accent border, solid fill, solid hover and accent text |
|
|
573
|
+
| `--ui-color-surface-elevated`, `--ui-color-info` | raised surface (menus, popovers) and the informational colour |
|
|
574
|
+
| `--ui-color-placeholder` | placeholder text (62% of the text colour, 4.5:1 or better on the field) |
|
|
575
|
+
| `--ui-color-foreground-on-warning` | text on a solid warning fill: dark when the warning colour is light (amber) |
|
|
576
|
+
| `--ui-ring-color`, `--ui-ring-width`, `--ui-ring-offset` | the focus ring |
|
|
577
|
+
| `--ui-control-height-{1..4}`, `--ui-control-font-size-{1..4}`, `--ui-control-padding-inline-{1..4}`, `--ui-control-radius-{1..4}` | the control scale: 24, 32, 40 and 48px (see below) |
|
|
578
|
+
| `--ui-motion-enter-easing`, `--ui-motion-exit-easing` | easing for things that appear and disappear |
|
|
579
|
+
|
|
580
|
+
### The default look
|
|
581
|
+
|
|
582
|
+
Light and dark, with the default amber accent (`radius` is 6px):
|
|
583
|
+
|
|
584
|
+
<p align="center">
|
|
585
|
+
<img src="https://raw.githubusercontent.com/ajaykr089/Editora/main/packages/ui-core/docs/images/look-light.png" alt="Buttons, fields, checkboxes, switches, badges, tabs and a card in the light theme" width="49%">
|
|
586
|
+
<img src="https://raw.githubusercontent.com/ajaykr089/Editora/main/packages/ui-core/docs/images/look-dark.png" alt="The same components in the dark theme" width="49%">
|
|
587
|
+
</p>
|
|
588
|
+
|
|
589
|
+
- **Buttons** are flat fills with no shadow. `variant` picks the colour (`primary`, `danger`, `success`, `warning`,
|
|
590
|
+
neutral `secondary`, `ghost`) and `recipe` the style: `solid` (default), `soft`, `surface`, `outline`, `ghost` or
|
|
591
|
+
`classic`. Status fills are a shade deeper than the status colour so white text reads at 4.5:1.
|
|
592
|
+
- **Fields** (input, select, textarea, combobox, pickers) share a hairline border that darkens on hover, and a 2px
|
|
593
|
+
focus ring drawn inside it.
|
|
594
|
+
- **`ui-field`** is flat: label, control and message with no box. `variant="surface"`, `outline`, `soft`, `contrast` or
|
|
595
|
+
`elevated` draw the box.
|
|
596
|
+
- **Tabs** are a line: a hairline under the tabs and a 2px accent line under the selected one. The boxed pill look is
|
|
597
|
+
`variant="segmented"`; `soft`, `outline`, `solid`, `cards` and `indicator` keep working.
|
|
598
|
+
- **Cards** have a single hairline border and no shadow. **Badges** are soft tinted labels without a border
|
|
599
|
+
(`variant="solid"` for a filled one).
|
|
600
|
+
- **Alerts** are a tinted fill with a hairline in the tone colour and a plain icon; the coloured bar on the leading edge
|
|
601
|
+
is opt-in (`indicator="line"`). **Slider**, **progress** and **meter** are flat tracks (4–6px) with a solid fill; the
|
|
602
|
+
slider thumb is a white circle.
|
|
603
|
+
- **Avatars** are a soft tint with initials. **Breadcrumbs** show the current page in bold, with no pill.
|
|
604
|
+
**Pagination** is a row of 32px buttons with a solid accent for the current page, no bar around them.
|
|
605
|
+
- **Calendar** days are plain cells; the selected day is solid accent, the range a soft tint.
|
|
606
|
+
- **Accordion** and **collapsible** are one hairline box with dividers; the accent bar on an open item is opt-in
|
|
607
|
+
(`indicator="line"` on the accordion). **Stepper** steps have no card: the current one is a solid circle.
|
|
608
|
+
- **Toggle** and **toggle group** are outlined buttons that turn a soft accent when pressed (no dot glyph unless you pass
|
|
609
|
+
`icon-on` / `icon-off`). **Toolbar**, **hover card** and **drawer** take the same flat surface as popovers.
|
|
610
|
+
- **Pin input** slots are 40px (one control tall), **empty state** and **file upload** use a primary button.
|
|
611
|
+
- **Tables** (`ui-table`, `ui-data-table`) are a hairline frame with quiet dividers and a subtle header; **tree** rows are
|
|
612
|
+
32px with a soft accent for the selected one; **timeline**, **form**, **fieldset** and **stepper** have no box
|
|
613
|
+
(`variant="surface"`, `outline`, `soft`, `contrast` or `elevated` on `ui-form` and `ui-fieldset` draw it).
|
|
614
|
+
- **Sidebar**, **app header** and **navigation menu** use the 32px control rhythm and a soft accent for the current
|
|
615
|
+
item; **transfer list**, **chart**, **wizard** and **gantt** drop their nested boxes and heavy shadows.
|
|
616
|
+
- **Command**, **selection popup**, **floating toolbar** and **quick actions** share the flat overlay surface.
|
|
617
|
+
- **Marquee**, **animated list**, **spinning text**, **icon cloud**, **orbiter** and **dock** keep their motion but drop the
|
|
618
|
+
card chrome: a hairline frame, no shadow. **Layout**, **container** and **section** use the theme radius, and their
|
|
619
|
+
boxed variants use the theme shadows.
|
|
620
|
+
|
|
621
|
+
### Control sizes
|
|
622
|
+
|
|
623
|
+
Buttons and form controls share one scale, so a row of mixed controls lines up:
|
|
624
|
+
|
|
625
|
+
| `size` | Height | Text |
|
|
626
|
+
| --- | --- | --- |
|
|
627
|
+
| `sm` (or `1`) | 24px | 12px |
|
|
628
|
+
| default (`md`, `2`) | 32px | 14px |
|
|
629
|
+
| `lg` (or `3`) | 40px | 16px |
|
|
630
|
+
|
|
631
|
+
This covers `ui-button`, `ui-input`, `ui-password-field`, `ui-number-field`, `ui-select`, `ui-combobox`,
|
|
632
|
+
`ui-multi-select`, `ui-tags-input`, `ui-toggle`, `ui-textarea` and the date and time pickers. `ui-button` also takes
|
|
633
|
+
`scale="4"` for 48px. The control radius follows the theme's `radius`.
|
|
634
|
+
|
|
635
|
+
To change a size for the whole page, set the tokens, for example `:root { --ui-control-height-2: 36px; }`. To
|
|
636
|
+
change one control, use `--ui-control-min-height` (buttons) or `--ui-min-height` (inputs) on it. The older
|
|
637
|
+
`components.button['height-md']`-style theme values still work if you set them.
|
|
638
|
+
|
|
639
|
+
The 24px size is small for touch. Buttons inside a small field (clear, show password, the dropdown arrow) stay 24px
|
|
640
|
+
tall so they still meet the WCAG 2.2 minimum target size, but prefer the default size on touch screens.
|
|
641
|
+
|
|
642
|
+
## Overlays
|
|
643
|
+
|
|
644
|
+
Popovers, menus, dropdowns, selects, comboboxes, tooltips and dialogs share one set of behaviours.
|
|
645
|
+
|
|
646
|
+
**They animate in and out.** A surface fades and scales in from the side it opens on, and plays a quicker exit before it
|
|
647
|
+
is removed, so it no longer disappears with a pop. With `prefers-reduced-motion: reduce` there is no animation. Tune it
|
|
648
|
+
with CSS variables on the page: `--ui-overlay-in-duration` (150ms), `--ui-overlay-out-duration` (100ms) and
|
|
649
|
+
`--ui-overlay-shift` (4px), plus `--ui-motion-enter-easing` and `--ui-motion-exit-easing`.
|
|
650
|
+
|
|
651
|
+
**They expose their state for CSS.** The open surface carries `data-state="open"` or `"closed"`, and positioned ones
|
|
652
|
+
also `data-side` (`top`, `right`, `bottom`, `left`) and `data-align` (`start`, `center`, `end`), as Radix does:
|
|
653
|
+
|
|
654
|
+
```css
|
|
655
|
+
.ui-menu-surface[data-side="top"][data-state="open"] {
|
|
656
|
+
/* your own rule */
|
|
657
|
+
}
|
|
658
|
+
```
|
|
659
|
+
|
|
660
|
+
**Popovers, menus, tooltips, dropdown-style menus and dialogs sit in the browser's top layer**, above every `z-index` on
|
|
661
|
+
the page, so a sticky header with `z-index: 9999` can no longer cover them. This uses `popover="manual"` (Chrome 114,
|
|
662
|
+
Safari 17, Firefox 125); older browsers keep the previous `z-index` stacking. Dismissal (Escape, click outside) is still
|
|
663
|
+
handled by the components.
|
|
664
|
+
|
|
665
|
+
Not in the top layer: the panels of `ui-select`, `ui-dropdown`, `ui-combobox` and `ui-multi-select`, which open inside
|
|
666
|
+
their own field and are clipped like it; `ui-hover-card` and `ui-drawer`. They do have the state attributes and the motion.
|
|
667
|
+
|
|
337
668
|
## Floating positioning
|
|
338
669
|
|
|
339
670
|
The positioning engine behind the menus, popovers and tooltips is available on its own, from
|
|
@@ -408,6 +739,9 @@ Working examples:
|
|
|
408
739
|
[guide](https://github.com/ajaykr089/Editora/blob/main/packages/ui-core/docs/FRAMEWORK_DIRECT_USAGE.md). For React,
|
|
409
740
|
use [`@editora/ui-react`](https://www.npmjs.com/package/@editora/ui-react).
|
|
410
741
|
|
|
742
|
+
`@editora/ui-vue`, `@editora/ui-svelte` and `@editora/ui-angular` are deprecated: they never grew past a few stub
|
|
743
|
+
components. Use `@editora/ui-core` directly instead.
|
|
744
|
+
|
|
411
745
|
## Good to know
|
|
412
746
|
|
|
413
747
|
- Components register when their module is imported, so the package is marked `sideEffects: true`. Import it before the
|
package/dist/accordion.cjs.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
ui-accordion[data-ui-accordion-root="true"] {
|
|
3
3
|
display: block;
|
|
4
4
|
overflow-anchor: none;
|
|
5
|
-
--ui-accordion-radius: var(--base-card-radius, var(--ui-radius,
|
|
5
|
+
--ui-accordion-radius: var(--base-card-radius, var(--ui-radius, 6px));
|
|
6
6
|
--ui-accordion-accent: var(--ui-color-primary, var(--ui-primary, #2563eb));
|
|
7
7
|
--ui-accordion-border-color: color-mix(in srgb, var(--ui-color-border, rgba(15, 23, 42, 0.16)) 82%, transparent);
|
|
8
8
|
--ui-accordion-border: 1px solid var(--ui-accordion-border-color);
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
--ui-accordion-surface-alt-base: var(--color-surface, var(--ui-color-surface-alt, #f8fafc));
|
|
12
12
|
--ui-accordion-surface: var(--ui-accordion-surface-base);
|
|
13
13
|
--ui-accordion-surface-alt: var(--ui-accordion-surface-alt-base);
|
|
14
|
-
--ui-accordion-hover-surface: color-mix(in srgb, var(--ui-accordion-accent) 6%, var(--ui-accordion-surface-alt));
|
|
15
|
-
--ui-accordion-open-surface:
|
|
14
|
+
--ui-accordion-hover-surface: var(--ui-color-fill, color-mix(in srgb, var(--ui-accordion-accent) 6%, var(--ui-accordion-surface-alt)));
|
|
15
|
+
--ui-accordion-open-surface: var(--ui-accordion-surface);
|
|
16
16
|
--ui-accordion-text: var(--ui-color-text, var(--ui-text, #202020));
|
|
17
17
|
--ui-accordion-muted: var(--ui-color-muted, var(--ui-muted, #646464));
|
|
18
18
|
--ui-accordion-focus-ring: var(--ui-color-focus-ring, var(--ui-focus-ring, #2563eb));
|
|
19
|
-
--ui-accordion-shadow: var(--base-card-shadow,
|
|
19
|
+
--ui-accordion-shadow: var(--base-card-shadow, none);
|
|
20
20
|
--ui-accordion-duration: 190ms;
|
|
21
21
|
--ui-accordion-easing: cubic-bezier(0.2, 0.8, 0.2, 1);
|
|
22
22
|
--ui-accordion-padding-x: 16px;
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
--ui-accordion-gap: var(--ui-default-gap, 8px);
|
|
25
25
|
--ui-accordion-title-size: var(--ui-default-font-size, 14px);
|
|
26
26
|
--ui-accordion-title-line-height: var(--ui-default-line-height, 20px);
|
|
27
|
-
--ui-accordion-title-weight:
|
|
27
|
+
--ui-accordion-title-weight: 500;
|
|
28
28
|
--ui-accordion-description-size: 12px;
|
|
29
29
|
--ui-accordion-description-line-height: 16px;
|
|
30
30
|
--ui-accordion-panel-size: 14px;
|
|
@@ -153,7 +153,7 @@
|
|
|
153
153
|
inset-block: 0;
|
|
154
154
|
inset-inline-start: 0;
|
|
155
155
|
inline-size: 0;
|
|
156
|
-
background:
|
|
156
|
+
background: var(--ui-accordion-accent);
|
|
157
157
|
transition: inline-size var(--ui-accordion-duration) var(--ui-accordion-easing);
|
|
158
158
|
pointer-events: none;
|
|
159
159
|
}
|
|
@@ -166,7 +166,8 @@
|
|
|
166
166
|
inline-size: var(--ui-accordion-indicator-size);
|
|
167
167
|
}
|
|
168
168
|
|
|
169
|
-
|
|
169
|
+
/* The accent bar on an open item is opt-in: indicator="line". */
|
|
170
|
+
ui-accordion[data-ui-accordion-root="true"]:not([indicator="line"]) > [data-ui-accordion-item]::before {
|
|
170
171
|
display: none;
|
|
171
172
|
}
|
|
172
173
|
|
|
@@ -199,11 +200,11 @@
|
|
|
199
200
|
}
|
|
200
201
|
|
|
201
202
|
ui-accordion[data-ui-accordion-root="true"] > [data-ui-accordion-item][open] [data-ui-accordion-trigger] {
|
|
202
|
-
color:
|
|
203
|
+
color: var(--ui-accordion-text);
|
|
203
204
|
}
|
|
204
205
|
|
|
205
206
|
ui-accordion[data-ui-accordion-root="true"] [data-ui-accordion-trigger]:focus-visible {
|
|
206
|
-
outline: 2px solid var(--ui-accordion-focus-ring);
|
|
207
|
+
outline: var(--ui-ring-width, 2px) solid var(--ui-ring-color, var(--ui-accordion-focus-ring));
|
|
207
208
|
outline-offset: -2px;
|
|
208
209
|
position: relative;
|
|
209
210
|
z-index: 1;
|
|
@@ -234,12 +235,12 @@
|
|
|
234
235
|
border-radius: var(--ui-accordion-badge-radius);
|
|
235
236
|
padding: 3px 8px;
|
|
236
237
|
font-size: 10px;
|
|
237
|
-
font-weight:
|
|
238
|
+
font-weight: 500;
|
|
238
239
|
letter-spacing: 0.02em;
|
|
239
240
|
text-transform: uppercase;
|
|
240
241
|
line-height: 1.2;
|
|
241
242
|
background: color-mix(in srgb, var(--ui-accordion-accent) 14%, transparent);
|
|
242
|
-
color: color-mix(in srgb, var(--ui-accordion-accent)
|
|
243
|
+
color: color-mix(in srgb, var(--ui-accordion-accent) 45%, var(--ui-color-text-strong, var(--ui-accordion-text)));
|
|
243
244
|
}
|
|
244
245
|
|
|
245
246
|
ui-accordion[data-ui-accordion-root="true"] [data-ui-accordion-chevron] {
|
|
@@ -353,7 +354,7 @@
|
|
|
353
354
|
color: HighlightText;
|
|
354
355
|
}
|
|
355
356
|
}
|
|
356
|
-
`;function u(c){const i=Number(c);if(!Number.isFinite(i))return-1;const r=Math.trunc(i);return r>=0?r:-1}function
|
|
357
|
+
`;function u(c){const i=Number(c);if(!Number.isFinite(i))return-1;const r=Math.trunc(i);return r>=0?r:-1}function v(c,i){if(c==null)return i;const r=c.toLowerCase();return r!=="false"&&r!=="0"&&r!=="no"}function m(c,i){if(!c)return[];if(!i){const o=u(c);return o>=0?[o]:[]}try{const o=JSON.parse(c);if(Array.isArray(o))return o.map(u).filter(e=>e>=0)}catch{}const r=u(c);return r>=0?[r]:[]}function h(c,i){return i?JSON.stringify(c):String(c[0]??-1)}function x(c,i="var(--base-card-radius, var(--ui-radius, 6px))"){if(!c||!c.trim())return i;const r=c.trim().toLowerCase();return r==="full"||r==="pill"?"999px":r==="square"||r==="none"?"0px":/^-?\d+(\.\d+)?$/.test(r)?`${r}px`:c.trim()}function y(c){return c instanceof HTMLElement&&c.hasAttribute("data-ui-accordion-item")}class g extends b.ElementBase{constructor(){super(),this._uid=`ui-accordion-${Math.random().toString(36).slice(2,8)}`,this._observer=null,this._panelResizeObserver=null,this._heightSyncRaf=0,this._syncingOpenAttr=!1,this._syncingDom=!1,this._syncingDomResetTimer=null,this._onClick=this._onClick.bind(this),this._onKeyDown=this._onKeyDown.bind(this),this._onMutations=this._onMutations.bind(this)}static get observedAttributes(){return["open","multiple","collapsible","headless","shape","elevation","variant","size","tone","radius","indicator"]}connectedCallback(){super.connectedCallback(),this.setAttribute("data-ui-accordion-root","true"),this._syncHostStyles(),this.addEventListener("click",this._onClick),this.addEventListener("keydown",this._onKeyDown),this._observer=new MutationObserver(this._onMutations),this._observer.observe(this,{childList:!0,subtree:!0,characterData:!0,attributes:!0}),typeof ResizeObserver<"u"&&(this._panelResizeObserver=new ResizeObserver(()=>{this._syncPanelHeights()}))}disconnectedCallback(){this.removeEventListener("click",this._onClick),this.removeEventListener("keydown",this._onKeyDown),this._observer&&(this._observer.disconnect(),this._observer=null),this._panelResizeObserver&&(this._panelResizeObserver.disconnect(),this._panelResizeObserver=null),this._heightSyncRaf&&(cancelAnimationFrame(this._heightSyncRaf),this._heightSyncRaf=0),this._syncingDomResetTimer!=null&&(clearTimeout(this._syncingDomResetTimer),this._syncingDomResetTimer=null),super.disconnectedCallback()}attributeChangedCallback(i,r,o){if(r!==o){if(i==="radius"||i==="shape"){this._syncHostStyles();return}if(this.isConnected){if(i==="open"){this._applyOpenState();return}this.requestRender()}}}get multiple(){return this.hasAttribute("multiple")}set multiple(i){i!==this.multiple&&(i?this.setAttribute("multiple",""):this.removeAttribute("multiple"))}get collapsible(){return v(this.getAttribute("collapsible"),!0)}set collapsible(i){this.setAttribute("collapsible",String(!!i))}get open(){const i=this._normalizeOpen(this._sourceItems());return this.multiple?i:i[0]??-1}set open(i){const r=Array.isArray(i)?i:[i];this._commitOpen(r.map(u).filter(o=>o>=0),!1)}_sourceItems(){return Array.from(this.children).filter(y).map((r,o)=>{const e=Array.from(r.children),t=e.find(n=>n.hasAttribute("data-ui-accordion-trigger"))||null,a=e.find(n=>n.hasAttribute("data-ui-accordion-panel"))||null;return{index:o,itemNode:r,trigger:t,panel:a,disabled:r.hasAttribute("disabled")||t?.hasAttribute("disabled")||!1,description:r.getAttribute("description")||r.getAttribute("data-description")||"",badge:r.getAttribute("badge")||r.getAttribute("data-badge")||""}})}_normalizeOpen(i){const r=m(this.getAttribute("open"),this.multiple),o=Array.from(new Set(r.map(u).filter(t=>t>=0&&t<i.length&&!i[t]?.disabled))).sort((t,a)=>t-a),e=i.findIndex(t=>!t.disabled);return this.multiple?this.collapsible||i.length===0||o.length>0?o:e>=0?[e]:[]:o.length>0?[o[0]]:this.collapsible||i.length===0?[]:e>=0?[e]:[]}_normalizeNext(i,r){const o=Array.from(new Set(i.map(u).filter(t=>t>=0&&t<r.length&&!r[t]?.disabled))).sort((t,a)=>t-a),e=r.findIndex(t=>!t.disabled);return this.multiple?this.collapsible||r.length===0||o.length>0?o:e>=0?[e]:[]:o.length>0?[o[0]]:this.collapsible||r.length===0?[]:e>=0?[e]:[]}_commitOpen(i,r){const o=this._sourceItems(),e=this._normalizeNext(i,o),t=h(e,this.multiple),a=this.getAttribute("open")??(this.multiple?"[]":"-1");if(t!==a&&(this._syncingOpenAttr=!0,this.setAttribute("open",t),this._syncingOpenAttr=!1,this._applyOpenState()),!r)return;const n=this.multiple?e:e[0]??-1;this.dispatchEvent(new CustomEvent("toggle",{detail:{open:n},bubbles:!0})),this.dispatchEvent(new CustomEvent("change",{detail:{open:n},bubbles:!0}))}_ensureStyleNode(){let i=this.querySelector(":scope > style[data-ui-accordion-style]");if(!i){i=document.createElement("style"),i.setAttribute("data-ui-accordion-style",""),i.textContent=p,this.prepend(i);return}i.textContent!==p&&(i.textContent=p)}_markSyncingDom(){this._syncingDom=!0,this._syncingDomResetTimer!=null&&clearTimeout(this._syncingDomResetTimer),this._syncingDomResetTimer=window.setTimeout(()=>{this._syncingDom=!1,this._syncingDomResetTimer=null},0)}_syncHostStyles(){const i=this.getAttribute("radius"),r=this.getAttribute("shape");if(i&&i.trim()){this.style.setProperty("--ui-accordion-radius",x(i));return}if(r==="square"){this.style.setProperty("--ui-accordion-radius","4px");return}if(r==="pill"){this.style.setProperty("--ui-accordion-radius","999px");return}this.style.removeProperty("--ui-accordion-radius")}_ensureGeneratedNodes(i){const{trigger:r,itemNode:o,description:e,badge:t}=i;if(!r)return;let a=r.querySelector("[data-ui-accordion-trailing]");a||(a=document.createElement("span"),a.setAttribute("data-ui-accordion-trailing",""),r.appendChild(a));let n=a.querySelector("[data-ui-accordion-generated-badge]");t?(n||(n=document.createElement("span"),n.setAttribute("data-ui-accordion-generated-badge",""),a.appendChild(n)),n.textContent=t):n&&n.remove();let s=a.querySelector("[data-ui-accordion-chevron]");s||(s=document.createElement("span"),s.setAttribute("data-ui-accordion-chevron",""),s.setAttribute("aria-hidden","true"),s.innerHTML=`
|
|
357
358
|
<svg width="16" height="16" viewBox="0 0 20 20" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round">
|
|
358
359
|
<path d="M5 7.5 10 12.5 15 7.5"></path>
|
|
359
360
|
</svg>
|
package/dist/accordion.esm.js
CHANGED
|
@@ -3,7 +3,7 @@ const p = `
|
|
|
3
3
|
ui-accordion[data-ui-accordion-root="true"] {
|
|
4
4
|
display: block;
|
|
5
5
|
overflow-anchor: none;
|
|
6
|
-
--ui-accordion-radius: var(--base-card-radius, var(--ui-radius,
|
|
6
|
+
--ui-accordion-radius: var(--base-card-radius, var(--ui-radius, 6px));
|
|
7
7
|
--ui-accordion-accent: var(--ui-color-primary, var(--ui-primary, #2563eb));
|
|
8
8
|
--ui-accordion-border-color: color-mix(in srgb, var(--ui-color-border, rgba(15, 23, 42, 0.16)) 82%, transparent);
|
|
9
9
|
--ui-accordion-border: 1px solid var(--ui-accordion-border-color);
|
|
@@ -12,12 +12,12 @@ const p = `
|
|
|
12
12
|
--ui-accordion-surface-alt-base: var(--color-surface, var(--ui-color-surface-alt, #f8fafc));
|
|
13
13
|
--ui-accordion-surface: var(--ui-accordion-surface-base);
|
|
14
14
|
--ui-accordion-surface-alt: var(--ui-accordion-surface-alt-base);
|
|
15
|
-
--ui-accordion-hover-surface: color-mix(in srgb, var(--ui-accordion-accent) 6%, var(--ui-accordion-surface-alt));
|
|
16
|
-
--ui-accordion-open-surface:
|
|
15
|
+
--ui-accordion-hover-surface: var(--ui-color-fill, color-mix(in srgb, var(--ui-accordion-accent) 6%, var(--ui-accordion-surface-alt)));
|
|
16
|
+
--ui-accordion-open-surface: var(--ui-accordion-surface);
|
|
17
17
|
--ui-accordion-text: var(--ui-color-text, var(--ui-text, #202020));
|
|
18
18
|
--ui-accordion-muted: var(--ui-color-muted, var(--ui-muted, #646464));
|
|
19
19
|
--ui-accordion-focus-ring: var(--ui-color-focus-ring, var(--ui-focus-ring, #2563eb));
|
|
20
|
-
--ui-accordion-shadow: var(--base-card-shadow,
|
|
20
|
+
--ui-accordion-shadow: var(--base-card-shadow, none);
|
|
21
21
|
--ui-accordion-duration: 190ms;
|
|
22
22
|
--ui-accordion-easing: cubic-bezier(0.2, 0.8, 0.2, 1);
|
|
23
23
|
--ui-accordion-padding-x: 16px;
|
|
@@ -25,7 +25,7 @@ const p = `
|
|
|
25
25
|
--ui-accordion-gap: var(--ui-default-gap, 8px);
|
|
26
26
|
--ui-accordion-title-size: var(--ui-default-font-size, 14px);
|
|
27
27
|
--ui-accordion-title-line-height: var(--ui-default-line-height, 20px);
|
|
28
|
-
--ui-accordion-title-weight:
|
|
28
|
+
--ui-accordion-title-weight: 500;
|
|
29
29
|
--ui-accordion-description-size: 12px;
|
|
30
30
|
--ui-accordion-description-line-height: 16px;
|
|
31
31
|
--ui-accordion-panel-size: 14px;
|
|
@@ -154,7 +154,7 @@ const p = `
|
|
|
154
154
|
inset-block: 0;
|
|
155
155
|
inset-inline-start: 0;
|
|
156
156
|
inline-size: 0;
|
|
157
|
-
background:
|
|
157
|
+
background: var(--ui-accordion-accent);
|
|
158
158
|
transition: inline-size var(--ui-accordion-duration) var(--ui-accordion-easing);
|
|
159
159
|
pointer-events: none;
|
|
160
160
|
}
|
|
@@ -167,7 +167,8 @@ const p = `
|
|
|
167
167
|
inline-size: var(--ui-accordion-indicator-size);
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
/* The accent bar on an open item is opt-in: indicator="line". */
|
|
171
|
+
ui-accordion[data-ui-accordion-root="true"]:not([indicator="line"]) > [data-ui-accordion-item]::before {
|
|
171
172
|
display: none;
|
|
172
173
|
}
|
|
173
174
|
|
|
@@ -200,11 +201,11 @@ const p = `
|
|
|
200
201
|
}
|
|
201
202
|
|
|
202
203
|
ui-accordion[data-ui-accordion-root="true"] > [data-ui-accordion-item][open] [data-ui-accordion-trigger] {
|
|
203
|
-
color:
|
|
204
|
+
color: var(--ui-accordion-text);
|
|
204
205
|
}
|
|
205
206
|
|
|
206
207
|
ui-accordion[data-ui-accordion-root="true"] [data-ui-accordion-trigger]:focus-visible {
|
|
207
|
-
outline: 2px solid var(--ui-accordion-focus-ring);
|
|
208
|
+
outline: var(--ui-ring-width, 2px) solid var(--ui-ring-color, var(--ui-accordion-focus-ring));
|
|
208
209
|
outline-offset: -2px;
|
|
209
210
|
position: relative;
|
|
210
211
|
z-index: 1;
|
|
@@ -235,12 +236,12 @@ const p = `
|
|
|
235
236
|
border-radius: var(--ui-accordion-badge-radius);
|
|
236
237
|
padding: 3px 8px;
|
|
237
238
|
font-size: 10px;
|
|
238
|
-
font-weight:
|
|
239
|
+
font-weight: 500;
|
|
239
240
|
letter-spacing: 0.02em;
|
|
240
241
|
text-transform: uppercase;
|
|
241
242
|
line-height: 1.2;
|
|
242
243
|
background: color-mix(in srgb, var(--ui-accordion-accent) 14%, transparent);
|
|
243
|
-
color: color-mix(in srgb, var(--ui-accordion-accent)
|
|
244
|
+
color: color-mix(in srgb, var(--ui-accordion-accent) 45%, var(--ui-color-text-strong, var(--ui-accordion-text)));
|
|
244
245
|
}
|
|
245
246
|
|
|
246
247
|
ui-accordion[data-ui-accordion-root="true"] [data-ui-accordion-chevron] {
|
|
@@ -383,7 +384,7 @@ function m(c, i) {
|
|
|
383
384
|
function h(c, i) {
|
|
384
385
|
return i ? JSON.stringify(c) : String(c[0] ?? -1);
|
|
385
386
|
}
|
|
386
|
-
function v(c, i = "var(--base-card-radius, var(--ui-radius,
|
|
387
|
+
function v(c, i = "var(--base-card-radius, var(--ui-radius, 6px))") {
|
|
387
388
|
if (!c || !c.trim()) return i;
|
|
388
389
|
const r = c.trim().toLowerCase();
|
|
389
390
|
return r === "full" || r === "pill" ? "999px" : r === "square" || r === "none" ? "0px" : /^-?\d+(\.\d+)?$/.test(r) ? `${r}px` : c.trim();
|