@jack-henry/jh-elements 2.0.0-beta.8

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 (39) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +26 -0
  3. package/README.md +13 -0
  4. package/components/badge/badge.js +73 -0
  5. package/components/button/button.js +953 -0
  6. package/components/card/card.js +333 -0
  7. package/components/checkbox/checkbox.js +601 -0
  8. package/components/checkbox-group/checkbox-group.js +241 -0
  9. package/components/divider/divider.js +91 -0
  10. package/components/icon/icon.js +96 -0
  11. package/components/input/input.js +1245 -0
  12. package/components/input-email/input-email.js +18 -0
  13. package/components/input-password/input-password.js +153 -0
  14. package/components/input-search/input-search.js +41 -0
  15. package/components/input-telephone/input-telephone.js +18 -0
  16. package/components/input-textarea/input-textarea.js +374 -0
  17. package/components/input-url/input-url.js +31 -0
  18. package/components/list-group/list-group.js +103 -0
  19. package/components/list-item/list-item.js +350 -0
  20. package/components/menu/menu.js +60 -0
  21. package/components/notification/notification.js +327 -0
  22. package/components/progress/progress.js +417 -0
  23. package/components/radio/radio.js +422 -0
  24. package/components/radio-group/radio-group.js +400 -0
  25. package/components/switch/switch.js +316 -0
  26. package/components/table/table.js +367 -0
  27. package/components/table-data-cell/table-data-cell.js +107 -0
  28. package/components/table-header-cell/table-header-cell.js +321 -0
  29. package/components/table-row/table-row.js +52 -0
  30. package/components/tag/tag.js +422 -0
  31. package/components/tag-group/tag-group.js +57 -0
  32. package/components/toast/toast.js +172 -0
  33. package/components/toast-controller/toast-controller.js +122 -0
  34. package/components/tooltip/tooltip.js +498 -0
  35. package/custom-elements.json +6864 -0
  36. package/index.d.ts +69 -0
  37. package/jsconfig.json +9 -0
  38. package/package.json +52 -0
  39. package/utils/themeProvider.js +32 -0
@@ -0,0 +1,367 @@
1
+ // SPDX-FileCopyrightText: 2025 Jack Henry
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ import { LitElement, css, html } from 'lit';
6
+ import { ifDefined } from 'lit/directives/if-defined.js';
7
+ import '../table-header-cell/table-header-cell.js';
8
+ import '../table-data-cell/table-data-cell.js';
9
+ import '../table-row/table-row.js';
10
+
11
+ let id = 0;
12
+
13
+ /**
14
+ * Table
15
+ * @cssprop --jh-table-color-text-striped-enabled - The striped row text color. Defaults to `--jh-color-content-primary-enabled`.
16
+ * @cssprop --jh-table-color-background-striped-enabled - The striped row background color. Defaults to `--jh-color-container-neutral-enabled`.
17
+ * @cssprop --jh-table-color-text-striped-hover - The striped row text color on hover. Defaults to `--jh-color-content-primary-hover`.
18
+ * @cssprop --jh-table-color-background-striped-hover - The striped row background color on hover. Defaults to `--jh-color-container-primary-hover`.
19
+ * @cssprop --jh-table-space-padding-vertical-medium - The vertical padding for medium padding for table-data-cells and table-header-cells. Defaults to `--jh-dimension-400`.
20
+ * @cssprop --jh-table-space-padding-vertical-small - The vertical padding for small padding for table-data-cells and table-header-cells. Defaults to `--jh-dimension-200`.
21
+ * @cssprop --jh-table-caption-color-text - The caption text color. Defaults to `--jh-color-content-primary-enabled`.
22
+ * @cssprop --jh-table-color-focus - The outline color when the scrollable table receives keyboard focus. Defaults to `--jh-border-focus-color`.
23
+ *
24
+ * @slot default - Use to insert table body.
25
+ * @slot jh-table-header - Use to insert table header row.
26
+ * @slot jh-table-footer - Use to insert table footer row.
27
+ * @slot jh-table-caption - Use to insert table caption.
28
+ * @slot jh-table-pagination - Use to insert pagination.
29
+ * @slot jh-table-toolbar - Use to insert toolbar.
30
+ * @customElement jh-table
31
+ */
32
+ export class JhTable extends LitElement {
33
+ /** @type {?Number} */
34
+ #id;
35
+
36
+ static get styles() {
37
+ return css`
38
+ :host {
39
+ box-sizing: border-box;
40
+ position: relative;
41
+ display: flex;
42
+ flex-direction: column;
43
+ max-height: 100%;
44
+ }
45
+ .table {
46
+ display: table;
47
+ table-layout: fixed;
48
+ width: 100%;
49
+ height: 100%;
50
+ }
51
+
52
+ /* vertical scroll styles for non-scrollable */
53
+ .table-wrapper {
54
+ position: relative;
55
+ overflow: auto;
56
+ flex: 1 1 auto;
57
+ }
58
+ :host([vertical-align='top']) {
59
+ --vertical-align: top;
60
+ --flex-vertical-align: flex-start;
61
+ }
62
+ :host([vertical-align='middle']) {
63
+ --vertical-align: middle;
64
+ --flex-vertical-align: center;
65
+ }
66
+ :host([vertical-align='bottom']) {
67
+ --vertical-align: bottom;
68
+ --flex-vertical-align: flex-end;
69
+ }
70
+ :host([striped]) .body::slotted(jh-table-row:nth-child(even)) {
71
+ --jh-table-row-color-text-enabled: var(
72
+ --jh-table-color-text-striped-enabled);
73
+ --jh-table-row-color-background-enabled: var(
74
+ --jh-table-color-background-striped-enabled,
75
+ var(--jh-color-container-neutral-enabled)
76
+ );
77
+ }
78
+ :host([striped]) .body::slotted(jh-table-row:nth-child(even):hover) {
79
+ --jh-table-row-color-text-hover: var(
80
+ --jh-table-color-text-striped-hover);
81
+ --jh-table-row-color-background-hover: var(
82
+ --jh-table-color-background-striped-hover,
83
+ var(--jh-color-container-neutral-hover)
84
+ );
85
+ }
86
+ :host([padding='medium']) {
87
+ --jh-table-data-cell-space-padding-top: var(
88
+ --jh-table-space-padding-vertical-medium
89
+ );
90
+ --jh-table-data-cell-space-padding-bottom: var(
91
+ --jh-table-space-padding-vertical-medium
92
+ );
93
+ --jh-table-header-cell-space-padding-top: var(
94
+ --jh-table-space-padding-vertical-medium
95
+ );
96
+ --jh-table-header-cell-space-padding-bottom: var(
97
+ --jh-table-space-padding-vertical-medium
98
+ );
99
+ }
100
+ :host([padding='small']) {
101
+ --jh-table-data-cell-space-padding-top: var(
102
+ --jh-table-space-padding-vertical-small,
103
+ var(--jh-dimension-200)
104
+ );
105
+ --jh-table-data-cell-space-padding-bottom: var(
106
+ --jh-table-space-padding-vertical-small,
107
+ var(--jh-dimension-200)
108
+ );
109
+ --jh-table-header-cell-space-padding-top: var(
110
+ --jh-table-space-padding-vertical-small,
111
+ var(--jh-dimension-200)
112
+ );
113
+ --jh-table-header-cell-space-padding-bottom: var(
114
+ --jh-table-space-padding-vertical-small,
115
+ var(--jh-dimension-200)
116
+ );
117
+ }
118
+ .header {
119
+ display: table-header-group;
120
+ }
121
+ .body {
122
+ display: table-row-group;
123
+ }
124
+ .footer {
125
+ display: table-footer-group;
126
+ /* these have to be passed down into the table-data-cell, can't target them directly from here because nested in slot */
127
+ --footer-line-height: var(--jh-font-body-bold-1-line-height);
128
+ --footer-font-weight: var(--jh-font-body-bold-1-font-weight);
129
+ --footer-font-size: var(--jh-font-body-bold-1-font-size);
130
+ --footer-font-family: var(--jh-font-body-bold-1-font-family);
131
+ }
132
+ :host([sticky-header]) .header {
133
+ position: sticky;
134
+ top: 0;
135
+ }
136
+ :host([sticky-footer]) .footer {
137
+ --jh-table-data-cell-color-border-top: var(
138
+ --jh-border-decorative-color
139
+ );
140
+ position: sticky;
141
+ bottom: 0;
142
+ }
143
+ :host([sticky-footer]) .body::slotted(jh-table-row:nth-last-of-type(2)) {
144
+ --jh-table-data-cell-color-border-bottom: transparent;
145
+ }
146
+
147
+ .display-caption {
148
+ color: var(
149
+ --jh-table-caption-color-text,
150
+ var(--jh-color-content-primary-enabled)
151
+ );
152
+ line-height: var(--jh-font-heading-bold-1-line-height);
153
+ font-weight: var(--jh-font-heading-bold-1-font-weight);
154
+ font-size: var(--jh-font-heading-bold-1-font-size);
155
+ font-family: var(--jh-font-heading-bold-1-font-family);
156
+ margin-bottom: var(--jh-dimension-200);
157
+ flex: 0 0 auto;
158
+ display: block;
159
+ }
160
+ .display-toolbar {
161
+ margin-bottom: var(--jh-dimension-200);
162
+ flex: 0 0 auto;
163
+ display: block;
164
+ }
165
+ .display-pagination {
166
+ margin-top: var(--jh-dimension-200);
167
+ flex: 0 0 auto;
168
+ display: block;
169
+ }
170
+
171
+ /* horizontal scrollable styles */
172
+ :host([scrollable]) .table-wrapper {
173
+ position: relative;
174
+ overflow-x: hidden;
175
+ flex: 1 1 auto;
176
+ /* display grid makes sticky work and shadows go till bottom. */
177
+ display: grid;
178
+ }
179
+
180
+ :host([scrollable]) .table-container {
181
+ overflow: scroll;
182
+ height: 100%;
183
+ /* removes bouncy scroll behavior in Safari and FF */
184
+ /* overscroll-behavior: none; */
185
+ }
186
+ :host([scrollable]) .scrollable {
187
+ width: auto;
188
+ position: relative;
189
+ }
190
+ .table-wrapper:has(.table-container:focus-visible) {
191
+ outline-color: var(
192
+ --jh-table-color-focus,
193
+ var(--jh-border-focus-color)
194
+ );
195
+ outline-width: var(--jh-border-focus-width);
196
+ outline-style: var(--jh-border-focus-style);
197
+ }
198
+ .table-wrapper:focus-visible {
199
+ outline: none;
200
+ }
201
+ `;
202
+ }
203
+
204
+ static get properties() {
205
+ return {
206
+ verticalAlign: {
207
+ type: String,
208
+ reflect: true,
209
+ attribute: 'vertical-align',
210
+ },
211
+ striped: {
212
+ type: Boolean,
213
+ reflect: true,
214
+ },
215
+ padding: {
216
+ type: String,
217
+ reflect: true,
218
+ },
219
+ accessibleLabel: {
220
+ type: String,
221
+ attribute: 'accessible-label',
222
+ },
223
+ stickyHeader: {
224
+ type: Boolean,
225
+ reflect: true,
226
+ attribute: 'sticky-header',
227
+ },
228
+ stickyFooter: {
229
+ type: Boolean,
230
+ reflect: true,
231
+ attribute: 'sticky-footer',
232
+ },
233
+ scrollable: {
234
+ type: Boolean,
235
+ },
236
+ };
237
+ }
238
+
239
+ constructor() {
240
+ super();
241
+ /**
242
+ * Sets the vertical alignment for each table cell.
243
+ * @attr vertical-align
244
+ * @type {'top' | 'middle' | 'bottom'}
245
+ */
246
+ this.verticalAlign = 'top';
247
+ /**
248
+ * Applies alternating background colors to rows.
249
+ * @attr striped
250
+ * @type {Boolean}
251
+ */
252
+ this.striped = false;
253
+ /**
254
+ * Adjusts the padding between the rows.
255
+ * @attr padding
256
+ * @type {'medium' | 'small'}
257
+ *
258
+ */
259
+ this.padding = 'medium';
260
+ /**
261
+ * Sets an `aria-label` to assist screen reader users when no visible caption is present.
262
+ * @attr accessible-label
263
+ * @type {String}
264
+ */
265
+ this.accessibleLabel = null;
266
+ /**
267
+ * Allows the header row to remain visible while scrolling.
268
+ * @attr sticky-header
269
+ * @type {Boolean}
270
+ */
271
+ this.stickyHeader = false;
272
+ /**
273
+ * Allows the footer row to remain visible while scrolling.
274
+ * @attr sticky-footer
275
+ * @type {Boolean}
276
+ */
277
+ this.stickyFooter = false;
278
+ /**
279
+ * Makes the table horizontally scrollable on smaller screens.
280
+ * @attr scrollable
281
+ * @type {Boolean}
282
+ */
283
+ this.scrollable = false;
284
+
285
+ this.addEventListener('jh-sort', this.#handleSort);
286
+ }
287
+
288
+ connectedCallback() {
289
+ super.connectedCallback();
290
+ this.#id = id++;
291
+ }
292
+
293
+ async firstUpdated() {
294
+ if (!this.scrollable) return;
295
+
296
+ const container = this.shadowRoot.querySelector('.table-container');
297
+ let scrollTable = this.shadowRoot.querySelector('.table');
298
+ await scrollTable.updateComplete;
299
+ let originalTableWidth = scrollTable.getBoundingClientRect().width;
300
+
301
+ this.observer = new ResizeObserver((entries) => {
302
+ entries.forEach((entry) => {
303
+ let table = entry.target.shadowRoot.querySelector('.table');
304
+ let tableContainer =
305
+ entry.target.shadowRoot.querySelector('.table-container');
306
+ if (table.scrollWidth > tableContainer.clientWidth) {
307
+ table.classList.add('scrollable');
308
+ } else {
309
+ if (table.scrollWidth >= originalTableWidth) {
310
+ table.classList.remove('scrollable');
311
+ tableContainer.removeAttribute('tabindex');
312
+ } else {
313
+ table.classList.add('scrollable');
314
+ tableContainer.setAttribute('tabindex', '0');
315
+ }
316
+ }
317
+ });
318
+ });
319
+
320
+ this.observer.observe(this);
321
+ }
322
+
323
+ #handleSlot(e) {
324
+ if (e.target.name === 'jh-table-pagination') {
325
+ e.target.classList.add('display-pagination');
326
+ }
327
+ if (e.target.name === 'jh-table-toolbar') {
328
+ e.target.classList.add('display-toolbar');
329
+ }
330
+ if (e.target.name === 'jh-table-caption') {
331
+ e.target.classList.add('display-caption');
332
+ }
333
+ }
334
+
335
+ //resets the sort state of all other header cells
336
+ #handleSort(e) {
337
+ const headerCells = this.shadowRoot
338
+ .querySelector('slot.header')
339
+ .assignedElements({ flatten: true })[0].children;
340
+ for (const cell of headerCells) {
341
+ if (cell.hasAttribute('sortable') && cell.id !== e.detail.id) {
342
+ cell.sorted = 'none';
343
+ cell.setAttribute('aria-sort', cell.sorted);
344
+ }
345
+ }
346
+ }
347
+
348
+ render() {
349
+ return html`
350
+ <slot name="jh-table-caption" id="table-caption-${this.#id}" @slotchange=${this.#handleSlot}></slot>
351
+ <slot name="jh-table-toolbar" @slotchange=${this.#handleSlot}></slot>
352
+ <div class="table-wrapper">
353
+ <div class="table-container" tabindex="${ifDefined(this.scrollable ? '0' : null)}">
354
+ <div class="table ${this.scrollable ? 'scrollable' : ''}" role="table"
355
+ aria-labelledby="table-caption-${this.#id}" aria-label=${ifDefined(this.accessibleLabel === '' ? null : this.accessibleLabel)}>
356
+ <slot name="jh-table-header" class="header" role="rowgroup"></slot>
357
+ <slot class="body" role="rowgroup"></slot>
358
+ <slot name="jh-table-footer" class="footer" role="rowgroup"></slot>
359
+ </div>
360
+ </div>
361
+ </div>
362
+ <slot name="jh-table-pagination" @slotchange=${this.#handleSlot}></slot>
363
+ `;
364
+ }
365
+ }
366
+
367
+ customElements.define('jh-table', JhTable);
@@ -0,0 +1,107 @@
1
+ // SPDX-FileCopyrightText: 2025 Jack Henry
2
+ //
3
+ // SPDX-License-Identifier: Apache-2.0
4
+
5
+ import { LitElement, css, html } from 'lit';
6
+
7
+ /**
8
+ * Table Cell
9
+ *
10
+ * @cssprop --jh-table-data-cell-color-text - The cell text color. Defaults to `--jh-color-content-primary-enabled`.
11
+ * @cssprop --jh-table-data-cell-color-background - The cell background color. Defaults to `--jh-color-container-primary-enabled`.
12
+ * @cssprop --jh-table-data-cell-color-border-top - The cell border top color. Defaults to `transparent`.
13
+ * @cssprop --jh-table-data-cell-color-border-right - The cell border right color. Defaults to `transparent`.
14
+ * @cssprop --jh-table-data-cell-color-border-left - The cell border left color. Defaults to `transparent`.
15
+ * @cssprop --jh-table-data-cell-color-border-bottom - The cell border bottom color. Defaults to `--jh-border-decorative-color`.
16
+ * @cssprop --jh-table-data-cell-border-top-width - The cell border top width. Defaults to `--jh-border-decorative-width`.
17
+ * @cssprop --jh-table-data-cell-border-right-width - The cell border right width. Defaults to `--jh-border-decorative-width`.
18
+ * @cssprop --jh-table-data-cell-border-left-width - The cell border left width. Defaults to `--jh-border-decorative-width`.
19
+ * @cssprop --jh-table-data-cell-border-bottom-width - The cell border bottom width. Defaults to `--jh-border-decorative-width`.
20
+ * @cssprop --jh-table-data-cell-border-top-style - The cell border top style. Defaults to `--jh-border-decorative-style`.
21
+ * @cssprop --jh-table-data-cell-border-right-style - The cell border right style. Defaults to `--jh-border-decorative-style`.
22
+ * @cssprop --jh-table-data-cell-border-left-style - The cell border left style. Defaults to `--jh-border-decorative-style`.
23
+ * @cssprop --jh-table-data-cell-border-bottom-style - The cell border bottom style. Defaults to `--jh-border-decorative-style`.
24
+ * @cssprop --jh-table-data-cell-space-padding-top - The cell padding top. Defaults to `--jh-dimension-400`.
25
+ * @cssprop --jh-table-data-cell-space-padding-right - The cell padding right. Defaults to `--jh-dimension-400`.
26
+ * @cssprop --jh-table-data-cell-space-padding-bottom - The cell padding bottom. Defaults to `--jh-dimension-400`.
27
+ * @cssprop --jh-table-data-cell-space-padding-left - The cell padding left. Defaults to `--jh-dimension-400`.
28
+ *
29
+ * @slot default - Use to insert content.
30
+ *
31
+ * @customElement jh-table-cell
32
+ */
33
+ export class JhTableDataCell extends LitElement {
34
+
35
+ /** @type {ElementInternals} */
36
+ #internals;
37
+
38
+ static get styles() {
39
+ return css`
40
+ :host {
41
+ border-top-color: var(--jh-table-data-cell-color-border-top, transparent);
42
+ border-top-width: var(--jh-table-data-cell-border-top-width, var(--jh-border-decorative-width));
43
+ border-top-style: var(--jh-table-data-cell-border-top-style, var(--jh-border-decorative-style));
44
+ border-right-color: var(--jh-table-data-cell-color-border-right, transparent);
45
+ border-right-width: var(--jh-table-data-cell-border-right-width, var(--jh-border-decorative-width));
46
+ border-right-style: var(--jh-table-data-cell-border-right-style, var(--jh-border-decorative-style));
47
+ border-left-color: var(--jh-table-data-cell-color-border-left, transparent);
48
+ border-left-width: var(--jh-table-data-cell-border-left-width, var(--jh-border-decorative-width));
49
+ border-left-style: var(--jh-table-data-cell-border-left-style, var(--jh-border-decorative-style));
50
+ border-bottom-color: var(--jh-table-data-cell-color-border-bottom, var(--jh-border-decorative-color));
51
+ border-bottom-width: var(--jh-table-data-cell-border-bottom-width, var(--jh-border-decorative-width));
52
+ border-bottom-style: var(--jh-table-data-cell-border-bottom-style, var(--jh-border-decorative-style));
53
+ color: var(--jh-table-data-cell-color-text, var(--jh-color-content-primary-enabled));
54
+ background-color: var(--jh-table-data-cell-color-background, var(--jh-color-container-primary-enabled));
55
+ padding-top: var(--jh-table-data-cell-space-padding-top, var(--jh-dimension-400));
56
+ padding-right: var(--jh-table-data-cell-space-padding-right, var(--jh-dimension-400));
57
+ padding-bottom: var(--jh-table-data-cell-space-padding-bottom, var(--jh-dimension-400));
58
+ padding-left: var(--jh-table-data-cell-space-padding-left, var(--jh-dimension-400));
59
+ vertical-align: var(--vertical-align, top);
60
+ line-height: var(--footer-line-height, var(--jh-font-body-regular-1-line-height));
61
+ font-weight: var(--footer-font-weight, var(--jh-font-body-regular-1-font-weight));
62
+ font-size: var(--footer-font-size, var(--jh-font-body-regular-1-font-size));
63
+ font-family: var(--footer-font-family, var(--jh-font-body-regular-1-font-family));
64
+ display: table-cell;
65
+ width: 100%;
66
+ }
67
+ :host([horizontal-align="left"]) {
68
+ text-align: left;
69
+ }
70
+ :host([horizontal-align="center"]) {
71
+ text-align: center;
72
+ }
73
+ :host([horizontal-align="right"]) {
74
+ text-align: right;
75
+ }
76
+ `;
77
+ }
78
+
79
+ static get properties() {
80
+ return {
81
+ horizontalAlign: {
82
+ type: String,
83
+ reflect: true,
84
+ attribute: 'horizontal-align'
85
+ }
86
+ };
87
+ }
88
+
89
+ constructor() {
90
+ super();
91
+ this.#internals = this.attachInternals();
92
+ this.#internals.role = 'cell';
93
+ /**
94
+ * Sets the horizontal alignment of the content.
95
+ * @attr horizontal-align
96
+ * @type {'left' | 'center' | 'right'}
97
+ *
98
+ */
99
+ this.horizontalAlign = 'left';
100
+ }
101
+
102
+ render() {
103
+ return html`<slot></slot>`;
104
+ }
105
+ }
106
+
107
+ customElements.define('jh-table-data-cell', JhTableDataCell);