@alacris/ui 0.0.0 → 0.1.1

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 (94) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +148 -1
  3. package/package.json +75 -3
  4. package/src/components/base.js +46 -0
  5. package/src/components/ui-accordion-item.js +157 -0
  6. package/src/components/ui-accordion.js +58 -0
  7. package/src/components/ui-alert.js +168 -0
  8. package/src/components/ui-app-bar.js +119 -0
  9. package/src/components/ui-autocomplete.js +371 -0
  10. package/src/components/ui-avatar.js +104 -0
  11. package/src/components/ui-backdrop.js +66 -0
  12. package/src/components/ui-badge.js +95 -0
  13. package/src/components/ui-bottom-app-bar.js +78 -0
  14. package/src/components/ui-bottom-nav.js +83 -0
  15. package/src/components/ui-breadcrumbs.js +100 -0
  16. package/src/components/ui-button-group.js +49 -0
  17. package/src/components/ui-button.js +143 -0
  18. package/src/components/ui-card.js +86 -0
  19. package/src/components/ui-carousel-item.js +53 -0
  20. package/src/components/ui-carousel.js +301 -0
  21. package/src/components/ui-checkbox.js +165 -0
  22. package/src/components/ui-chip-set.js +90 -0
  23. package/src/components/ui-chip.js +226 -0
  24. package/src/components/ui-container.js +59 -0
  25. package/src/components/ui-date-picker.js +774 -0
  26. package/src/components/ui-dialog.js +179 -0
  27. package/src/components/ui-divider.js +58 -0
  28. package/src/components/ui-drawer.js +169 -0
  29. package/src/components/ui-fab-menu.js +122 -0
  30. package/src/components/ui-fab.js +117 -0
  31. package/src/components/ui-icon-button.js +112 -0
  32. package/src/components/ui-icon.js +64 -0
  33. package/src/components/ui-list-item.js +166 -0
  34. package/src/components/ui-list.js +38 -0
  35. package/src/components/ui-loading-indicator.js +74 -0
  36. package/src/components/ui-menu-item.js +117 -0
  37. package/src/components/ui-menu.js +192 -0
  38. package/src/components/ui-nav-item.js +138 -0
  39. package/src/components/ui-nav-rail.js +111 -0
  40. package/src/components/ui-option.js +85 -0
  41. package/src/components/ui-pagination.js +173 -0
  42. package/src/components/ui-progress.js +100 -0
  43. package/src/components/ui-radio-group.js +104 -0
  44. package/src/components/ui-radio.js +143 -0
  45. package/src/components/ui-rating.js +126 -0
  46. package/src/components/ui-search.js +318 -0
  47. package/src/components/ui-select.js +418 -0
  48. package/src/components/ui-sheet.js +205 -0
  49. package/src/components/ui-side-sheet.js +221 -0
  50. package/src/components/ui-skeleton.js +89 -0
  51. package/src/components/ui-slider.js +266 -0
  52. package/src/components/ui-snackbar.js +233 -0
  53. package/src/components/ui-spinner.js +101 -0
  54. package/src/components/ui-split-button.js +158 -0
  55. package/src/components/ui-stack.js +37 -0
  56. package/src/components/ui-step.js +91 -0
  57. package/src/components/ui-stepper.js +86 -0
  58. package/src/components/ui-surface.js +51 -0
  59. package/src/components/ui-switch.js +153 -0
  60. package/src/components/ui-tab-panel.js +54 -0
  61. package/src/components/ui-tab.js +116 -0
  62. package/src/components/ui-table-footer.js +141 -0
  63. package/src/components/ui-table-toolbar.js +219 -0
  64. package/src/components/ui-table.js +735 -0
  65. package/src/components/ui-tabs.js +178 -0
  66. package/src/components/ui-text-field.js +319 -0
  67. package/src/components/ui-text.js +36 -0
  68. package/src/components/ui-time-picker.js +753 -0
  69. package/src/components/ui-toggle-button.js +170 -0
  70. package/src/components/ui-toggle-group.js +111 -0
  71. package/src/components/ui-toolbar.js +64 -0
  72. package/src/components/ui-tooltip.js +148 -0
  73. package/src/index.js +121 -0
  74. package/src/motion/animate.js +145 -0
  75. package/src/motion/flip.js +46 -0
  76. package/src/motion/index.js +4 -0
  77. package/src/motion/presence.js +104 -0
  78. package/src/motion/ripple.js +108 -0
  79. package/src/theme/apply-theme.js +142 -0
  80. package/src/theme/create-theme.js +70 -0
  81. package/src/theme/index.js +5 -0
  82. package/src/tokens/color.js +237 -0
  83. package/src/tokens/index.js +14 -0
  84. package/src/tokens/sys.js +76 -0
  85. package/src/tokens/system.js +114 -0
  86. package/src/tokens/typography.js +189 -0
  87. package/src/util/focus.js +89 -0
  88. package/src/util/form.js +69 -0
  89. package/src/util/icons.js +161 -0
  90. package/src/util/keys.js +110 -0
  91. package/src/util/position.js +102 -0
  92. package/src/util/table.js +230 -0
  93. package/types/elements.d.ts +78 -0
  94. package/types/index.d.ts +168 -0
@@ -0,0 +1,219 @@
1
+ // <ui-table-toolbar> — DataGrid chrome: title, selection count, quick filter,
2
+ // column visibility, density, and CSV export. Built from <ui-search>,
3
+ // <ui-icon-button>, <ui-menu>, and <ui-checkbox>.
4
+ //
5
+ // <ui-table-toolbar headline="Nutrition" quick-filter column-menu
6
+ // density-menu csv-export
7
+ // columns=${cols} hidden-columns=${hidden}
8
+ // @filter=${…} @density=${…}
9
+ // @column-visibility=${…} @export=${…}>
10
+ // <ui-button slot="actions">Add</ui-button>
11
+ // </ui-table-toolbar>
12
+ //
13
+ // @prop {string} headline=''
14
+ // @prop {string} supporting=''
15
+ // @prop {number} selectedCount=0 — when >0 the bar switches to the
16
+ // "N selected" selection state
17
+ // @prop {string} filter='' — quick-filter value
18
+ // @prop {boolean} quickFilter=false
19
+ // @prop {boolean} columnMenu=false
20
+ // @prop {boolean} densityMenu=false
21
+ // @prop {boolean} csvExport=false
22
+ // @prop {Array} columns=[] — { key, label } (JSON or property)
23
+ // @prop {Array} hiddenColumns=[]
24
+ // @prop {string} density='standard' — compact | standard | comfortable
25
+ // @prop {boolean} disabled=false
26
+ // @event filter — quick filter changed; detail: { value }
27
+ // @event density — density chosen; detail: { density }
28
+ // @event column-visibility — a column was toggled; detail: { hidden }
29
+ // @event export — export requested; detail: { format: 'csv' }
30
+ // @slot headline — replaces the headline text
31
+ // @slot supporting
32
+ // @slot actions — extra trailing controls (after the built-in tools)
33
+ // @part bar, titles, tools
34
+ // @vars see `t` below (`themeVars.names`)
35
+
36
+ import { define, html, css, vars, computed, signal, effect, each } from '@alacris/core';
37
+ import { sys } from '../tokens/sys.js';
38
+ import { base, focusRingOn } from './base.js';
39
+ import './ui-search.js';
40
+ import './ui-icon-button.js';
41
+ import './ui-menu.js';
42
+ import './ui-menu-item.js';
43
+ import './ui-checkbox.js';
44
+
45
+ const t = vars('ui-table-toolbar', {
46
+ height: '64px',
47
+ bg: sys.color.surface,
48
+ selectedBg: sys.color.secondaryContainer,
49
+ selectedFg: sys.color.onSecondaryContainer,
50
+ panelBg: sys.color.surfaceContainer,
51
+ radius: sys.radius.xs,
52
+ elevation: sys.elevation[2],
53
+ });
54
+
55
+ const styles = css`
56
+ :host { display: none; }
57
+ :host(.show) { display: block; }
58
+ .bar {
59
+ display: flex;
60
+ align-items: center;
61
+ gap: ${sys.space(3)};
62
+ min-block-size: ${t.height};
63
+ padding-inline: ${sys.space(4)};
64
+ background: ${t.bg};
65
+ }
66
+ .bar.picking {
67
+ background: ${t.selectedBg};
68
+ color: ${t.selectedFg};
69
+ }
70
+ .titles { flex: 1; min-inline-size: 0; }
71
+ .headline {
72
+ margin: 0;
73
+ font: ${sys.type.titleLg};
74
+ letter-spacing: ${sys.tracking.titleLg};
75
+ color: ${sys.color.onSurface};
76
+ }
77
+ .bar.picking .headline { color: inherit; }
78
+ .supporting {
79
+ margin: 0;
80
+ font: ${sys.type.bodyMd};
81
+ letter-spacing: ${sys.tracking.bodyMd};
82
+ color: ${sys.color.onSurfaceVariant};
83
+ }
84
+ .tools {
85
+ display: flex;
86
+ align-items: center;
87
+ gap: ${sys.space(1)};
88
+ flex: none;
89
+ }
90
+ .quick-filter { inline-size: 220px; }
91
+ .col-wrap { position: relative; }
92
+ .panel {
93
+ position: absolute;
94
+ inset-inline-end: 0;
95
+ inset-block-start: calc(100% + ${sys.space(1)});
96
+ z-index: 3;
97
+ min-inline-size: 220px;
98
+ max-block-size: 320px;
99
+ overflow: auto;
100
+ padding: ${sys.space(2)};
101
+ background: ${t.panelBg};
102
+ border-radius: ${t.radius};
103
+ box-shadow: ${t.elevation};
104
+ display: flex;
105
+ flex-direction: column;
106
+ gap: ${sys.space(1)};
107
+ }
108
+ ${focusRingOn('.panel')}
109
+ `;
110
+
111
+ define('ui-table-toolbar', {
112
+ props: {
113
+ headline: '',
114
+ supporting: '',
115
+ selectedCount: 0,
116
+ filter: '',
117
+ quickFilter: false,
118
+ columnMenu: false,
119
+ densityMenu: false,
120
+ csvExport: false,
121
+ columns: [],
122
+ hiddenColumns: [],
123
+ density: 'standard',
124
+ disabled: false,
125
+ },
126
+ styles: [base, styles],
127
+ setup(p, host) {
128
+ const {
129
+ headline, supporting, selectedCount, filter, quickFilter, columnMenu,
130
+ densityMenu, csvExport, columns, hiddenColumns, density, disabled,
131
+ } = p;
132
+
133
+ const colsOpen = signal(false);
134
+ const picking = computed(() => (selectedCount() || 0) > 0);
135
+ const hiddenSet = computed(() => new Set(hiddenColumns() || []));
136
+
137
+ const hasChrome = computed(() => !!(
138
+ headline() || supporting() || picking() ||
139
+ quickFilter() || columnMenu() || densityMenu() || csvExport()
140
+ ));
141
+ effect(() => host.classList.toggle('show', hasChrome()));
142
+
143
+ const toggleCol = (key) => {
144
+ const next = new Set(hiddenColumns() || []);
145
+ if (next.has(key)) next.delete(key);
146
+ else next.add(key);
147
+ const visible = (columns() || []).filter((c) => c && !next.has(c.key));
148
+ if (!visible.length) return;
149
+ host.emit('column-visibility', { hidden: [...next] });
150
+ };
151
+
152
+ effect(() => {
153
+ if (!colsOpen()) return;
154
+ const close = (e) => {
155
+ if (!host.contains(e.target)) colsOpen.set(false);
156
+ };
157
+ document.addEventListener('pointerdown', close);
158
+ return () => document.removeEventListener('pointerdown', close);
159
+ });
160
+
161
+ return html`
162
+ <div class=${() => (picking() ? 'bar picking' : 'bar')} part="bar"
163
+ role="toolbar" aria-label=${() => headline() || 'Table toolbar'}>
164
+ <div class="titles" part="titles">
165
+ <div class="headline" id="table-title">
166
+ <slot name="headline">${() =>
167
+ picking() ? `${selectedCount()} selected` : headline()
168
+ }</slot>
169
+ </div>
170
+ <div class="supporting" ?hidden=${picking}>
171
+ <slot name="supporting">${supporting}</slot>
172
+ </div>
173
+ </div>
174
+ <div class="tools" part="tools">
175
+ ${() => (quickFilter() ? html`
176
+ <div class="quick-filter">
177
+ <ui-search label="Search" value=${filter} ?disabled=${disabled}
178
+ @input=${(e) => host.emit('filter', { value: e.detail.value })}>
179
+ </ui-search>
180
+ </div>` : null)}
181
+ ${() => (columnMenu() ? html`
182
+ <div class="col-wrap">
183
+ <ui-icon-button icon="view-column" label="Show columns"
184
+ disabled=${disabled}
185
+ @click=${() => colsOpen.set(!colsOpen())}></ui-icon-button>
186
+ ${() => (colsOpen() ? html`
187
+ <div class="panel" role="group" aria-label="Show columns">
188
+ ${each(
189
+ () => columns() || [],
190
+ (col) => html`
191
+ <ui-checkbox label=${() => col().label}
192
+ checked=${() => !hiddenSet().has(col().key)}
193
+ disabled=${disabled}
194
+ @change=${(e) => { e.stopPropagation(); toggleCol(col().key); }}>
195
+ </ui-checkbox>`,
196
+ (c) => c.key,
197
+ )}
198
+ </div>` : null)}
199
+ </div>` : null)}
200
+ ${() => (densityMenu() ? html`
201
+ <ui-menu @select=${(e) => host.emit('density', { density: e.detail.value })}>
202
+ <ui-icon-button slot="anchor" icon="table-rows" label="Density"
203
+ disabled=${disabled}></ui-icon-button>
204
+ <ui-menu-item value="compact">Compact</ui-menu-item>
205
+ <ui-menu-item value="standard">Standard</ui-menu-item>
206
+ <ui-menu-item value="comfortable">Comfortable</ui-menu-item>
207
+ </ui-menu>` : null)}
208
+ ${() => (csvExport() ? html`
209
+ <ui-icon-button icon="download" label="Export CSV" disabled=${disabled}
210
+ @click=${() => host.emit('export', { format: 'csv' })}>
211
+ </ui-icon-button>` : null)}
212
+ <slot name="actions"></slot>
213
+ </div>
214
+ </div>`;
215
+ },
216
+ });
217
+
218
+ export const tag = 'ui-table-toolbar';
219
+ export const themeVars = t;