@carbon/ibm-products-web-components 0.0.1-canary.3564

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 (69) hide show
  1. package/.storybook/Preview.ts +161 -0
  2. package/.storybook/_container.scss +73 -0
  3. package/.storybook/container.ts +41 -0
  4. package/.storybook/main.ts +25 -0
  5. package/.storybook/manager.ts +13 -0
  6. package/.storybook/preview-head.html +3 -0
  7. package/.storybook/templates/with-layer.scss +38 -0
  8. package/.storybook/templates/with-layer.ts +90 -0
  9. package/.storybook/theme.ts +12 -0
  10. package/LICENSE +201 -0
  11. package/es/components/side-panel/defs.d.ts +39 -0
  12. package/es/components/side-panel/defs.js +51 -0
  13. package/es/components/side-panel/defs.js.map +1 -0
  14. package/es/components/side-panel/index.d.ts +9 -0
  15. package/es/components/side-panel/index.js +9 -0
  16. package/es/components/side-panel/index.js.map +1 -0
  17. package/es/components/side-panel/side-panel.d.ts +539 -0
  18. package/es/components/side-panel/side-panel.js +837 -0
  19. package/es/components/side-panel/side-panel.js.map +1 -0
  20. package/es/components/side-panel/side-panel.scss.js +13 -0
  21. package/es/components/side-panel/side-panel.scss.js.map +1 -0
  22. package/es/components/side-panel/side-panel.test.d.ts +7 -0
  23. package/es/components/side-panel/side-panel.test.js +56 -0
  24. package/es/components/side-panel/side-panel.test.js.map +1 -0
  25. package/es/globals/internal/handle.d.ts +18 -0
  26. package/es/globals/internal/handle.js +8 -0
  27. package/es/globals/internal/handle.js.map +1 -0
  28. package/es/globals/settings.d.ts +15 -0
  29. package/es/globals/settings.js +28 -0
  30. package/es/globals/settings.js.map +1 -0
  31. package/es/index.d.ts +9 -0
  32. package/es/index.js +9 -0
  33. package/es/index.js.map +1 -0
  34. package/lib/components/side-panel/defs.d.ts +39 -0
  35. package/lib/components/side-panel/defs.js +51 -0
  36. package/lib/components/side-panel/defs.js.map +1 -0
  37. package/lib/components/side-panel/index.d.ts +9 -0
  38. package/lib/components/side-panel/side-panel.d.ts +539 -0
  39. package/lib/components/side-panel/side-panel.test.d.ts +7 -0
  40. package/lib/globals/internal/handle.d.ts +18 -0
  41. package/lib/globals/settings.d.ts +15 -0
  42. package/lib/globals/settings.js +32 -0
  43. package/lib/globals/settings.js.map +1 -0
  44. package/lib/index.d.ts +9 -0
  45. package/netlify.toml +8 -0
  46. package/package.json +96 -0
  47. package/scss/components/side-panel/side-panel.scss +302 -0
  48. package/scss/components/side-panel/story-styles.scss +46 -0
  49. package/src/components/side-panel/defs.ts +46 -0
  50. package/src/components/side-panel/index.ts +10 -0
  51. package/src/components/side-panel/side-panel.mdx +106 -0
  52. package/src/components/side-panel/side-panel.scss +302 -0
  53. package/src/components/side-panel/side-panel.stories.ts +525 -0
  54. package/src/components/side-panel/side-panel.test.ts +52 -0
  55. package/src/components/side-panel/side-panel.ts +980 -0
  56. package/src/components/side-panel/story-styles.scss +46 -0
  57. package/src/globals/internal/handle.ts +19 -0
  58. package/src/globals/settings.ts +22 -0
  59. package/src/index.ts +10 -0
  60. package/src/typings/resources.d.ts +26 -0
  61. package/tasks/build.js +165 -0
  62. package/tools/rollup-plugin-icon-paths.js +39 -0
  63. package/tools/rollup-plugin-icons.js +73 -0
  64. package/tools/rollup-plugin-lit-scss.js +89 -0
  65. package/tools/svg-result-carbon-icon-loader.js +28 -0
  66. package/tools/svg-result-carbon-icon.js +42 -0
  67. package/tools/vite-svg-result-carbon-icon-loader.ts +65 -0
  68. package/tsconfig.json +36 -0
  69. package/vite.config.ts +32 -0
@@ -0,0 +1,525 @@
1
+ /**
2
+ * @license
3
+ *
4
+ * Copyright IBM Corp. 2024, 2024
5
+ *
6
+ * This source code is licensed under the Apache-2.0 license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ */
9
+
10
+ import { html } from 'lit';
11
+ import { SIDE_PANEL_SIZE, SIDE_PANEL_PLACEMENT } from './side-panel';
12
+ import './index';
13
+ // import Settings from '@carbon/icons/lib/settings/16';
14
+ // import Trashcan from '@carbon/icons/lib/trash-can/16';
15
+ import { prefix } from '../../globals/settings';
16
+
17
+ import styles from './story-styles.scss?lit';
18
+ import { BUTTON_KIND } from '@carbon/web-components/es/components/button/defs.js';
19
+ import '@carbon/web-components/es/components/button/index.js';
20
+ import '@carbon/web-components/es/components/text-input/index.js';
21
+ import '@carbon/web-components/es/components/textarea/index.js';
22
+
23
+ const toggleButton = () => {
24
+ document.querySelector(`${prefix}-side-panel`)?.toggleAttribute('open');
25
+ };
26
+
27
+ const nextStep = () => {
28
+ document
29
+ .querySelector(`${prefix}-side-panel`)
30
+ ?.setAttribute('current-step', '1');
31
+ };
32
+
33
+ const prevStep = () => {
34
+ document
35
+ .querySelector(`${prefix}-side-panel`)
36
+ ?.setAttribute('current-step', '0');
37
+ };
38
+
39
+ const sizes = {
40
+ // 'default (md)': null,
41
+ [`Extra small size (${SIDE_PANEL_SIZE.EXTRA_SMALL})`]:
42
+ SIDE_PANEL_SIZE.EXTRA_SMALL,
43
+ [`Small size (${SIDE_PANEL_SIZE.SMALL})`]: SIDE_PANEL_SIZE.SMALL,
44
+ [`Medium size (default) (${SIDE_PANEL_SIZE.MEDIUM})`]: SIDE_PANEL_SIZE.MEDIUM,
45
+ [`Large size (${SIDE_PANEL_SIZE.LARGE})`]: SIDE_PANEL_SIZE.LARGE,
46
+ [`Extra Extra Large size (${SIDE_PANEL_SIZE.EXTRA_EXTRA_LARGE})`]:
47
+ SIDE_PANEL_SIZE.EXTRA_EXTRA_LARGE,
48
+ };
49
+
50
+ const placements = {
51
+ // 'default (right)': null,
52
+ left: SIDE_PANEL_PLACEMENT.LEFT,
53
+ 'right (default)': SIDE_PANEL_PLACEMENT.RIGHT,
54
+ };
55
+
56
+ const contents = {
57
+ Empty: 0,
58
+ 'Brief content': 1,
59
+ 'Longer content': 2,
60
+ };
61
+
62
+ const storyPrefix = 'side-panel-stories__';
63
+
64
+ const getContent = (index) => {
65
+ switch (index) {
66
+ case 1:
67
+ return html`
68
+ <style>
69
+ ${styles}
70
+ </style>
71
+ <h5>Section</h5>
72
+ <cds-text-input
73
+ label="Input A"
74
+ id="side-panel-story-text-input-a"
75
+ class="${storyPrefix}text-input"
76
+ ></cds-text-input>
77
+ <cds-text-input
78
+ label="Input B"
79
+ id="side-panel-story-text-input-b"
80
+ class="${storyPrefix}text-input"
81
+ ></cds-text-input>
82
+ `;
83
+ case 2:
84
+ return html`
85
+ <style>
86
+ ${styles}
87
+ </style>
88
+ <h5>Section</h5>
89
+ <div class="${storyPrefix}text-inputs">
90
+ <cds-text-input
91
+ label="Input A"
92
+ id="side-panel-story-text-input-a"
93
+ ></cds-text-input>
94
+ <cds-text-input
95
+ label="Input B"
96
+ id="side-panel-story-text-input-b"
97
+ ></cds-text-input>
98
+ </div>
99
+ <div class="${storyPrefix}text-inputs">
100
+ <cds-text-input
101
+ label="Input C"
102
+ id="side-panel-story-text-input-c"
103
+ ></cds-text-input>
104
+ <cds-text-input
105
+ label="Input D"
106
+ id="side-panel-story-text-input-d"
107
+ ></cds-text-input>
108
+ </div>
109
+ <div class="${storyPrefix}textarea-container">
110
+ <cds-textarea
111
+ label="Notes"
112
+ value="This is a text area"
113
+ ></cds-textarea>
114
+ <cds-textarea
115
+ label="Notes"
116
+ value="This is a text area"
117
+ ></cds-textarea>
118
+ <cds-textarea
119
+ label="Notes"
120
+ value="This is a text area"
121
+ ></cds-textarea>
122
+ </div>
123
+ `;
124
+
125
+ default:
126
+ return null;
127
+ }
128
+ };
129
+
130
+ const labels = {
131
+ 'No label': 0,
132
+ 'Shorter label': 1,
133
+ 'Longer label': 2,
134
+ };
135
+
136
+ const getLabel = (index) => {
137
+ switch (index) {
138
+ case 1:
139
+ return 'A short label';
140
+ case 2:
141
+ return 'A longer label that might go on for a little bit';
142
+ default:
143
+ return '';
144
+ }
145
+ };
146
+
147
+ const subtitles = {
148
+ 'No subtitle': 0,
149
+ 'Short subtitle': 1,
150
+ 'Longer subtitle': 2,
151
+ };
152
+ const getSubTitle = (index) => {
153
+ switch (index) {
154
+ case 1:
155
+ return html`<div slot="subtitle">This is your subtitle slot.</div>`;
156
+ case 2:
157
+ return html`<div slot="subtitle">
158
+ I am your subtitle slot for <strong>adding detail</strong> that can be
159
+ one or two lines.
160
+ </div>`;
161
+ default:
162
+ return null;
163
+ }
164
+ };
165
+
166
+ const actionToolbarItems = {
167
+ 'No action toolbar': 0,
168
+ 'With action toolbar': 1,
169
+ };
170
+
171
+ const getActionToolbarItems = (index) => {
172
+ switch (index) {
173
+ case 1:
174
+ return html`
175
+ <cds-button slot="action-toolbar">Copy</cds-button>
176
+ <cds-button
177
+ slot="action-toolbar"
178
+ aria-label="Settings"
179
+ has-icon-only="true"
180
+ kind=${BUTTON_KIND.GHOST}
181
+ size="sm"
182
+ tooltip-text="Settings"
183
+ >
184
+ </cds-button>
185
+ <cds-button
186
+ slot="action-toolbar"
187
+ aria-label="Delete"
188
+ has-icon-only="true"
189
+ kind=${BUTTON_KIND.GHOST}
190
+ size="sm"
191
+ tooltip-text="Delete"
192
+ >
193
+ </cds-button>
194
+ `;
195
+ default:
196
+ return null;
197
+ }
198
+ };
199
+
200
+ const actionItems = {
201
+ 'No actions': 0,
202
+ 'One button': 1,
203
+ 'Two buttons with ghost': 2,
204
+ 'Two buttons with danger': 3,
205
+ 'Three buttons with ghost': 4,
206
+ 'Three buttons with danger': 5,
207
+ 'Too many buttons': 6,
208
+ };
209
+
210
+ // TODO: There are problems switching this
211
+ const getActionItems = (index) => {
212
+ switch (index) {
213
+ case 1:
214
+ return html`<cds-button key="p" slot="actions" kind=${BUTTON_KIND.PRIMARY}
215
+ >Primary</cds-button
216
+ >`;
217
+ case 2:
218
+ return html`
219
+ <cds-button slot="actions" kind=${BUTTON_KIND.GHOST}>Ghost</cds-button>
220
+ <cds-button slot="actions" kind=${BUTTON_KIND.PRIMARY}
221
+ >Primary</cds-button
222
+ >
223
+ `;
224
+ case 3:
225
+ return html` <cds-button slot="actions" kind=${BUTTON_KIND.DANGER}
226
+ >Danger</cds-button
227
+ >
228
+ <cds-button slot="actions" kind=${BUTTON_KIND.PRIMARY}
229
+ >Primary</cds-button
230
+ >`;
231
+ case 4:
232
+ return html` <cds-button slot="actions" kind=${BUTTON_KIND.GHOST}
233
+ >Ghost</cds-button
234
+ >
235
+ <cds-button slot="actions" kind=${BUTTON_KIND.SECONDARY}
236
+ >Secondary</cds-button
237
+ >
238
+ <cds-button slot="actions" kind=${BUTTON_KIND.PRIMARY}
239
+ >Primary</cds-button
240
+ >`;
241
+ case 5:
242
+ return html`<cds-button
243
+ key="danger"
244
+ slot="actions"
245
+ kind=${BUTTON_KIND.DANGER}
246
+ >Danger</cds-button
247
+ >
248
+ <cds-button key="secondary" slot="actions" kind=${BUTTON_KIND.SECONDARY}
249
+ >Secondary</cds-button
250
+ >
251
+ <cds-button key="primary" slot="actions" kind=${BUTTON_KIND.PRIMARY}
252
+ >Primary</cds-button
253
+ >`;
254
+ case 6:
255
+ return html`<cds-button
256
+ key="danger"
257
+ slot="actions"
258
+ kind=${BUTTON_KIND.DANGER}
259
+ >Danger</cds-button
260
+ >
261
+ <cds-button key="tertiary" slot="actions" kind=${BUTTON_KIND.TERTIARY}
262
+ >Tertiary</cds-button
263
+ >
264
+ <cds-button key="secondary" slot="actions" kind=${BUTTON_KIND.SECONDARY}
265
+ >Secondary</cds-button
266
+ >
267
+ <cds-button key="primary" slot="actions" kind=${BUTTON_KIND.PRIMARY}
268
+ >Primary</cds-button
269
+ >`;
270
+ default:
271
+ return null;
272
+ }
273
+ };
274
+
275
+ const slugs = {
276
+ 'No Slug': 0,
277
+ 'With Slug': 1,
278
+ };
279
+
280
+ const getSlug = (index) => {
281
+ switch (index) {
282
+ case 1:
283
+ return html`<cds-slug size="xs" alignment="bottom-right">
284
+ <div slot="body-text">
285
+ <p class="secondary">AI Explained</p>
286
+ <h1>84%</h1>
287
+ <p class="secondary bold">Confidence score</p>
288
+ <!-- //cspell: disable -->
289
+ <p class="secondary">
290
+ Lorem ipsum dolor sit amet, di os consectetur adipiscing elit, sed
291
+ do eiusmod tempor incididunt ut fsil labore et dolore magna aliqua.
292
+ </p>
293
+ <!-- //cspell: enable -->
294
+ <hr />
295
+ <p class="secondary">Model type</p>
296
+ <p class="bold">Foundation model</p>
297
+ </div>
298
+ </cds-slug>`;
299
+ default:
300
+ return null;
301
+ }
302
+ };
303
+
304
+ const defaultTemplate = {
305
+ args: {
306
+ actionItems: getActionItems(1),
307
+ actionToolbarItems: getActionToolbarItems(0),
308
+ animateTitle: true,
309
+ class: 'a-user-class',
310
+ closeIconDescription: 'Close panel',
311
+ condensedActions: false,
312
+ content: getContent(2),
313
+ includeOverlay: true,
314
+ label: getLabel(2),
315
+ open: false,
316
+ placement: SIDE_PANEL_PLACEMENT.RIGHT,
317
+ preventCloseOnClickOutside: false,
318
+ selectorPageContent: '#page-content-selector',
319
+ selectorInitialFocus: '#side-panel-story-text-input-a',
320
+ size: SIDE_PANEL_SIZE.MEDIUM,
321
+ slideIn: false,
322
+ slug: getSlug(0),
323
+ subtitle: getSubTitle(1),
324
+ title:
325
+ 'This title is testing a very long title to see how this behaves with a longer title. It needs to be long enough to trigger overflow when collapsed.',
326
+ },
327
+ argTypes: {
328
+ actionItems: {
329
+ control: 'select',
330
+ description: 'Slot (actions)',
331
+ options: actionItems,
332
+ },
333
+ actionToolbarItems: {
334
+ control: 'select',
335
+ description: 'Slot (action-toolbar)',
336
+ options: actionToolbarItems,
337
+ },
338
+ animateTitle: {
339
+ control: 'boolean',
340
+ description: 'animate-title (Title animates on scroll)',
341
+ },
342
+ class: {
343
+ control: 'text',
344
+ description: 'class',
345
+ },
346
+ closeIconDescription: {
347
+ control: 'text',
348
+ description: 'Close icon description',
349
+ },
350
+ condensedActions: {
351
+ control: 'boolean',
352
+ description: 'condensed-actions',
353
+ },
354
+ content: {
355
+ control: 'select',
356
+ description: 'Slot (default), panel contents',
357
+ options: contents,
358
+ },
359
+ includeOverlay: {
360
+ control: 'boolean',
361
+ description: 'include-overlay',
362
+ },
363
+ label: {
364
+ control: 'select',
365
+ description: 'label',
366
+ options: labels,
367
+ },
368
+ open: {
369
+ control: 'boolean',
370
+ description: 'open',
371
+ },
372
+ placement: {
373
+ control: 'select',
374
+ description: 'placement',
375
+ options: placements,
376
+ },
377
+ preventCloseOnClickOutside: {
378
+ control: 'boolean',
379
+ description: 'prevent-close-on-click-outside',
380
+ },
381
+ selectorPageContent: {
382
+ control: 'text',
383
+ description: 'selector-page-content',
384
+ },
385
+ selectorInitialFocus: {
386
+ control: 'text',
387
+ description: 'selector-initial-focus',
388
+ },
389
+ size: {
390
+ control: 'select',
391
+ description: 'size',
392
+ options: sizes,
393
+ },
394
+ slideIn: {
395
+ control: 'boolean',
396
+ description: 'slide-in',
397
+ },
398
+ slug: {
399
+ control: 'select',
400
+ description: 'slug (AI slug)',
401
+ options: slugs,
402
+ },
403
+ subtitle: {
404
+ control: 'select',
405
+ description: 'Slot (subtitle)',
406
+ options: subtitles,
407
+ },
408
+ title: {
409
+ control: 'text',
410
+ description: 'title',
411
+ },
412
+ },
413
+ render: (args) => {
414
+ return html`
415
+ <div class="${storyPrefix}story-container">
416
+ <div class="${storyPrefix}story-header"></div>
417
+ <div id="page-content-selector" class="${storyPrefix}story-content">
418
+ <cds-button @click="${toggleButton}">Toggle side-panel</cds-button>
419
+ </div>
420
+ </div>
421
+ <c4p-side-panel
422
+ ?animate-title=${args.animateTitle}
423
+ ?condensed-actions=${args.condensedActions}
424
+ current-step="0"
425
+ ?include-overlay=${args.includeOverlay && !args.slideIn}
426
+ selector-initial-focus=${args.selectorInitialFocus}
427
+ label-text="${args.label}"
428
+ ?open=${args.open}
429
+ placement=${args.placement}
430
+ ?prevent-close-on-click-outside=${args.preventCloseOnClickOutside}
431
+ selector-page-content=${args.selectorPageContent}
432
+ size=${args.size}
433
+ ?slide-in=${args.slideIn}
434
+ .title=${args.title}
435
+ @cds-side-panel-navigate-back=${prevStep}
436
+ >
437
+ <!-- default slotted content -->
438
+ ${args.content}
439
+ <cds-button @click="${nextStep}">Step two</cds-button>
440
+
441
+ <!-- slotted subtitle slotted content -->
442
+ ${args.subtitle}
443
+
444
+ <!-- slotted action toolbar cds-buttons -->
445
+ ${args.actionToolbarItems}
446
+
447
+ <!-- slotted action items cds-buttons -->
448
+ ${args.actionItems}
449
+
450
+ <!-- slotted slug -->
451
+ ${args.slug}
452
+ </c4p-side-panel>
453
+ `;
454
+ },
455
+ };
456
+
457
+ export const SlideOver = {
458
+ ...defaultTemplate,
459
+ };
460
+
461
+ export const SlideIn = {
462
+ ...defaultTemplate,
463
+ args: {
464
+ ...defaultTemplate.args,
465
+ slideIn: true,
466
+ },
467
+ };
468
+
469
+ export const WithActionToolbar = {
470
+ ...defaultTemplate,
471
+ args: {
472
+ ...defaultTemplate.args,
473
+ actionToolbarItems: getActionToolbarItems(1),
474
+ },
475
+ };
476
+
477
+ export const SpecifyElementToHaveFocus = {
478
+ ...defaultTemplate,
479
+ args: {
480
+ ...defaultTemplate.args,
481
+ focusSelector: '#side-panel-story-text-input-a',
482
+ label: getLabel(0),
483
+ },
484
+ argTypes: {
485
+ ...defaultTemplate.argTypes,
486
+ focusSelector: {
487
+ control: 'text',
488
+ description: 'selector-primary-focus',
489
+ },
490
+ },
491
+ };
492
+
493
+ export const WithStaticTitle = {
494
+ ...defaultTemplate,
495
+ args: {
496
+ ...defaultTemplate.args,
497
+ animateTitle: false,
498
+ label: getLabel(0),
499
+ },
500
+ };
501
+
502
+ export const WithStaticTitleAndActionToolbar = {
503
+ ...defaultTemplate,
504
+ args: {
505
+ ...defaultTemplate.args,
506
+ actionToolbarItems: getActionToolbarItems(1),
507
+ animateTitle: false,
508
+ label: getLabel(0),
509
+ },
510
+ };
511
+
512
+ export const WithoutTitle = {
513
+ ...defaultTemplate,
514
+ args: {
515
+ ...defaultTemplate.args,
516
+ label: getLabel(0),
517
+ title: '',
518
+ },
519
+ };
520
+
521
+ const meta = {
522
+ title: 'Experimental/SidePanel',
523
+ };
524
+
525
+ export default meta;
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Copyright IBM Corp. 2024, 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
8
+ vi.mock('@carbon/icons/lib/close/20', () => vi.fn().mockReturnValue({}));
9
+ import { describe, expect, it, vi } from 'vitest';
10
+ import { render, html } from 'lit';
11
+
12
+ const defaultProps = {
13
+ animateTitle: true,
14
+ includeOverlay: true,
15
+ slideIn: false,
16
+ selectorInitialFocus: '',
17
+ label: '',
18
+ open: true,
19
+ placement: 'right',
20
+ preventCloseOnClickOutside: false,
21
+ selectorPageContent: '',
22
+ size: 'md',
23
+ title: 'Side panel title',
24
+ };
25
+
26
+ const template = (props = defaultProps) =>
27
+ html`
28
+ <c4p-side-panel
29
+ ?animate-title=${props.animateTitle}
30
+ ?include-overlay=${props.includeOverlay && !props.slideIn}
31
+ selector-initial-focus=${props.selectorInitialFocus}
32
+ label-text="${props.label}"
33
+ ?open=${props.open}
34
+ placement=${props.placement}
35
+ ?prevent-close-on-click-outside=${props.preventCloseOnClickOutside}
36
+ selector-page-content=${props.selectorPageContent}
37
+ size=${props.size}
38
+ ?slide-in=${props.slideIn}
39
+ .title=${props.title}
40
+ >
41
+ content
42
+ </c4p-side-panel>
43
+ `;
44
+
45
+ describe('c4p-side-panel', () => {
46
+ it('should render a side panel', async () => {
47
+ render(template(), document.body);
48
+ await Promise.resolve();
49
+ const elem = document.body.querySelector('c4p-side-panel' as any);
50
+ expect(elem).toBeDefined();
51
+ });
52
+ });