vira 31.18.0 → 31.18.2

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.
@@ -1,8 +1,7 @@
1
1
  import { assertWrap, check } from '@augment-vir/assert';
2
2
  import { omitObjectKeys, wrapInTry } from '@augment-vir/common';
3
- import { extractEventTarget } from '@augment-vir/web';
4
3
  import { css, defineElementEvent, html, listen, nothing } from 'element-vir';
5
- import { lucideIcons, X16Icon } from '../icons/index.js';
4
+ import { Plus16Icon, X16Icon } from '../icons/index.js';
6
5
  import { viraFontCssVars } from '../styles/font.js';
7
6
  import { viraFormCssVars } from '../styles/form-styles.js';
8
7
  import { ViraColorVariant, ViraEmphasis, ViraSize } from '../styles/form-variants.js';
@@ -13,6 +12,7 @@ import { ViraCheckbox } from './vira-checkbox.element.js';
13
12
  import { ViraError } from './vira-error.element.js';
14
13
  import { ViraInput, ViraInputType } from './vira-input.element.js';
15
14
  import { ViraSelect } from './vira-select.element.js';
15
+ import { ViraTextArea } from './vira-text-area.element.js';
16
16
  /**
17
17
  * An editor for arbitrary JSON values, optionally constrained by a standard JSON Schema
18
18
  * ({@link ViraJsonSchema}).
@@ -48,24 +48,10 @@ export const ViraJsonForm = defineViraElement()({
48
48
  justify-content: flex-end;
49
49
  }
50
50
 
51
- .json-raw-textarea {
52
- margin: 0;
53
- padding: 10px 12px;
54
- border: 1px solid ${viraFormCssVars['vira-form-border-color'].value};
55
- border-radius: ${viraFormCssVars['vira-form-wrapper-radius'].value};
56
- background-color: ${viraFormCssVars['vira-form-background-color'].value};
57
- color: ${viraFormCssVars['vira-form-foreground-color'].value};
51
+ ${ViraTextArea}.json-raw-textarea {
52
+ width: 100%;
58
53
  font-family: ${viraFontCssVars['vira-monospace'].value};
59
54
  font-size: ${viraFormCssVars['vira-form-small-text-size'].value};
60
- box-sizing: border-box;
61
- width: 100%;
62
- min-height: 240px;
63
- resize: vertical;
64
- }
65
-
66
- .json-raw-textarea:focus {
67
- outline: none;
68
- border-color: ${viraFormCssVars['vira-form-focus-outline-color'].value};
69
55
  }
70
56
 
71
57
  .json-validation-errors {
@@ -80,73 +66,71 @@ export const ViraJsonForm = defineViraElement()({
80
66
  }
81
67
 
82
68
  .json-group {
83
- display: flex;
84
- flex-direction: column;
85
- gap: 8px;
86
- padding: 10px 12px;
87
- border: 1px solid ${viraFormCssVars['vira-form-border-color'].value};
88
- border-radius: ${viraFormCssVars['vira-form-wrapper-radius'].value};
89
- background-color: ${viraFormCssVars['vira-form-background-color'].value};
90
- }
91
-
92
- .json-group-header {
93
- display: flex;
94
- align-items: center;
95
- gap: 8px;
96
- }
97
-
98
- .json-group-header-title {
99
- flex-grow: 1;
100
- font-weight: ${viraFormCssVars['vira-form-label-font-weight'].value};
101
- color: ${viraFormCssVars['vira-form-secondary-body-foreground'].value};
102
- font-size: ${viraFormCssVars['vira-form-small-text-size'].value};
69
+ border-collapse: separate;
70
+ border-spacing: 0;
71
+ width: 100%;
72
+ box-sizing: border-box;
103
73
  }
104
74
 
105
- .json-row {
106
- display: flex;
107
- gap: 8px;
75
+ .json-group-nested {
76
+ margin-top: 4px;
77
+ padding-left: 12px;
78
+ padding-bottom: 8px;
79
+ border-left: 2px solid ${viraFormCssVars['vira-form-border-color'].value};
80
+ border-bottom: 2px solid ${viraFormCssVars['vira-form-border-color'].value};
108
81
  }
109
82
 
110
- .json-row-primitive {
111
- align-items: center;
83
+ .json-row-primitive > td {
84
+ padding: 4px 8px 4px 0;
85
+ vertical-align: middle;
112
86
  }
113
87
 
114
- .json-row-nested {
115
- align-items: flex-start;
88
+ .json-row-primitive > td:last-child {
89
+ padding-right: 0;
116
90
  }
117
91
 
118
- .json-row-label {
119
- flex-shrink: 0;
92
+ td.json-row-label {
93
+ text-align: left;
120
94
  min-width: 80px;
95
+ white-space: nowrap;
121
96
  font-weight: ${viraFormCssVars['vira-form-label-font-weight'].value};
122
- word-break: break-word;
123
- }
124
-
125
- .json-row-nested .json-row-label {
126
- padding-top: 10px;
127
97
  }
128
98
 
129
- .json-row-editor {
130
- flex-grow: 1;
131
- min-width: 0;
132
- display: flex;
133
- flex-direction: column;
99
+ td.json-row-editor {
100
+ width: 100%;
134
101
  }
135
102
 
136
- .json-row-editor > * {
103
+ td.json-row-editor > * {
137
104
  width: 100%;
138
105
  max-width: 100%;
106
+ box-sizing: border-box;
139
107
  }
140
108
 
141
- .json-row-delete {
142
- flex-shrink: 0;
109
+ td.json-row-delete {
143
110
  width: 24px;
111
+ text-align: center;
112
+ }
113
+
114
+ .json-row-nested > td {
115
+ padding: 4px 0;
116
+ }
117
+
118
+ .json-row-nested-header {
144
119
  display: flex;
145
- justify-content: center;
120
+ align-items: center;
121
+ gap: 8px;
122
+ margin-bottom: 4px;
146
123
  }
147
124
 
148
- .json-row-nested .json-row-delete {
149
- padding-top: 4px;
125
+ .json-row-nested-header > .json-row-label {
126
+ flex-grow: 1;
127
+ font-weight: ${viraFormCssVars['vira-form-label-font-weight'].value};
128
+ word-break: break-word;
129
+ }
130
+
131
+ .json-type-tag {
132
+ font-weight: normal;
133
+ color: ${viraFormCssVars['vira-form-secondary-body-foreground'].value};
150
134
  }
151
135
 
152
136
  .json-value-with-switcher {
@@ -174,8 +158,10 @@ export const ViraJsonForm = defineViraElement()({
174
158
  .json-add-row {
175
159
  display: flex;
176
160
  align-items: center;
161
+ justify-content: flex-end;
177
162
  gap: 6px;
178
163
  flex-wrap: wrap;
164
+ padding: 8px 0;
179
165
  }
180
166
 
181
167
  .json-add-row ${ViraInput}, .json-add-row ${ViraSelect} {
@@ -195,12 +181,14 @@ export const ViraJsonForm = defineViraElement()({
195
181
  }
196
182
 
197
183
  .json-empty-note {
184
+ display: block;
185
+ padding: 4px 0;
198
186
  color: ${viraFormCssVars['vira-form-placeholder-color'].value};
199
187
  font-style: italic;
200
188
  font-size: ${viraFormCssVars['vira-form-small-text-size'].value};
201
189
  }
202
190
  `,
203
- render({ inputs, state, dispatch, events, updateState }) {
191
+ render({ inputs, state, dispatch, events, updateState, host }) {
204
192
  const isDisabled = !!inputs.isDisabled;
205
193
  const resolveContext = createResolveContext(inputs.schema);
206
194
  function jsonPrimitiveToString(entry) {
@@ -397,8 +385,9 @@ export const ViraJsonForm = defineViraElement()({
397
385
  function renderPlusButton({ isAddDisabled, tooltip, onClick, }) {
398
386
  return html `
399
387
  <${ViraButton.assign({
400
- icon: lucideIcons.Plus,
401
- color: ViraColorVariant.Plain,
388
+ icon: Plus16Icon,
389
+ color: ViraColorVariant.Positive,
390
+ buttonSize: ViraSize.Small,
402
391
  isDisabled: isAddDisabled,
403
392
  })}
404
393
  title=${tooltip}
@@ -411,7 +400,7 @@ export const ViraJsonForm = defineViraElement()({
411
400
  ></${ViraButton}>
412
401
  `;
413
402
  }
414
- function renderObjectAddControl({ pathKey, allowedTypes, canAdd, onAdd, }) {
403
+ function renderObjectAddControl({ pathKey, allowedTypes, canAdd, disabledReason, onAdd, }) {
415
404
  if (allowedTypes.length === 0) {
416
405
  return nothing;
417
406
  }
@@ -420,7 +409,7 @@ export const ViraJsonForm = defineViraElement()({
420
409
  const onlyType = assertWrap.isDefined(allowedTypes[0]);
421
410
  return renderPlusButton({
422
411
  isAddDisabled,
423
- tooltip: `Add ${viraJsonTypeLabels[onlyType]}`,
412
+ tooltip: isAddDisabled ? disabledReason : `Add ${viraJsonTypeLabels[onlyType]}`,
424
413
  onClick: () => onAdd(onlyType),
425
414
  });
426
415
  }
@@ -442,7 +431,9 @@ export const ViraJsonForm = defineViraElement()({
442
431
  ></${ViraSelect}>
443
432
  ${renderPlusButton({
444
433
  isAddDisabled,
445
- tooltip: `Add ${viraJsonTypeLabels[selectedType]}`,
434
+ tooltip: isAddDisabled
435
+ ? disabledReason
436
+ : `Add ${viraJsonTypeLabels[selectedType]}`,
446
437
  onClick: () => onAdd(selectedType),
447
438
  })}
448
439
  `;
@@ -502,8 +493,14 @@ export const ViraJsonForm = defineViraElement()({
502
493
  })}
503
494
  `;
504
495
  }
505
- function renderObjectGroup(path, value, schema, onDelete) {
496
+ function getNestedTypeLabel(schema, value) {
497
+ const concreteType = getJsonType(value);
498
+ const narrowedSchema = pickBranchForType(schema, concreteType, resolveContext);
499
+ return (getSchemaTitle(narrowedSchema, resolveContext) || viraJsonTypeLabels[concreteType]);
500
+ }
501
+ function renderObjectGroup(path, value, schema) {
506
502
  const pathKey = pathToKey(path);
503
+ const isRoot = path.length === 0;
507
504
  const requiredKeys = new Set(getRequiredProperties(schema, resolveContext));
508
505
  const definedProperties = getDefinedProperties(schema, resolveContext);
509
506
  const definedKeys = new Set(Object.keys(definedProperties));
@@ -529,20 +526,34 @@ export const ViraJsonForm = defineViraElement()({
529
526
  }
530
527
  }
531
528
  : undefined;
529
+ if (isChildNested) {
530
+ return html `
531
+ <tr class="json-row-nested">
532
+ <td colspan="3">
533
+ <div class="json-row-nested-header">
534
+ <span class="json-row-label">
535
+ ${key}${isRequired ? '*' : ''}
536
+ <span class="json-type-tag">
537
+ : ${getNestedTypeLabel(childSchema, childValue)}
538
+ </span>
539
+ </span>
540
+ ${childOnDelete ? renderDeleteButton(childOnDelete) : nothing}
541
+ </div>
542
+ ${renderValue(childPath, childValue, childSchema)}
543
+ </td>
544
+ </tr>
545
+ `;
546
+ }
532
547
  return html `
533
- <div
534
- class="json-row ${isChildNested ? 'json-row-nested' : 'json-row-primitive'}"
535
- >
536
- <span class="json-row-label">${key}${isRequired ? '*' : ''}</span>
537
- <span class="json-row-editor">
538
- ${renderValue(childPath, childValue, childSchema, isChildNested ? childOnDelete : undefined)}
539
- </span>
540
- <span class="json-row-delete">
541
- ${!isChildNested && childOnDelete
542
- ? renderDeleteButton(childOnDelete)
543
- : nothing}
544
- </span>
545
- </div>
548
+ <tr class="json-row-primitive">
549
+ <td class="json-row-label">${key}${isRequired ? '*' : ''}</td>
550
+ <td class="json-row-editor">
551
+ ${renderValue(childPath, childValue, childSchema)}
552
+ </td>
553
+ <td class="json-row-delete">
554
+ ${childOnDelete ? renderDeleteButton(childOnDelete) : nothing}
555
+ </td>
556
+ </tr>
546
557
  `;
547
558
  });
548
559
  const missingDefinedKeys = [...definedKeys].filter((key) => !(key in value));
@@ -555,8 +566,9 @@ export const ViraJsonForm = defineViraElement()({
555
566
  return html `
556
567
  <${ViraButton.assign({
557
568
  text: `"${key}"`,
558
- icon: lucideIcons.Plus,
559
- color: ViraColorVariant.Plain,
569
+ icon: Plus16Icon,
570
+ color: ViraColorVariant.Positive,
571
+ buttonSize: ViraSize.Small,
560
572
  })}
561
573
  ${listen('click', () => {
562
574
  emitReplaceAt([
@@ -573,21 +585,27 @@ export const ViraJsonForm = defineViraElement()({
573
585
  const additionalAllowedTypes = additional.allowed
574
586
  ? getAllowedJsonTypes(additional.schema, resolveContext)
575
587
  : [];
588
+ const arbitraryAddDisabledReason = trimmedPendingKey
589
+ ? `Field "${trimmedPendingKey}" already exists.`
590
+ : 'Enter a field name to add.';
576
591
  const arbitraryAddRow = additional.allowed && !isDisabled
577
592
  ? html `
578
- <div class="json-add-row">
579
- <${ViraInput.assign({
593
+ <tr>
594
+ <td colspan="3">
595
+ <div class="json-add-row">
596
+ <${ViraInput.assign({
580
597
  value: pendingKey,
581
598
  placeholder: 'new field name',
582
599
  })}
583
- ${listen(ViraInput.events.valueChange, (event) => {
600
+ ${listen(ViraInput.events.valueChange, (event) => {
584
601
  setPendingKey(pathKey, event.detail);
585
602
  })}
586
- ></${ViraInput}>
587
- ${renderObjectAddControl({
603
+ ></${ViraInput}>
604
+ ${renderObjectAddControl({
588
605
  pathKey,
589
606
  allowedTypes: additionalAllowedTypes,
590
607
  canAdd: canAddArbitraryField,
608
+ disabledReason: arbitraryAddDisabledReason,
591
609
  onAdd: (type) => {
592
610
  if (!canAddArbitraryField) {
593
611
  return;
@@ -599,33 +617,41 @@ export const ViraJsonForm = defineViraElement()({
599
617
  clearPending(pathKey);
600
618
  },
601
619
  })}
602
- </div>
620
+ </div>
621
+ </td>
622
+ </tr>
603
623
  `
604
624
  : nothing;
605
- const title = getSchemaTitle(schema, resolveContext) || 'object';
606
625
  return html `
607
- <div class="json-group">
608
- <div class="json-group-header">
609
- <span class="json-group-header-title">${title}</span>
610
- ${onDelete ? renderDeleteButton(onDelete) : nothing}
611
- </div>
612
- ${rowTemplates.length === 0 && suggestedKeyButtons.length === 0
626
+ <table class="json-group ${isRoot ? '' : 'json-group-nested'}">
627
+ <tbody>
628
+ ${rowTemplates.length === 0 && suggestedKeyButtons.length === 0
613
629
  ? html `
614
- <span class="json-empty-note">(empty object)</span>
615
- `
630
+ <tr>
631
+ <td colspan="3">
632
+ <span class="json-empty-note">(empty object)</span>
633
+ </td>
634
+ </tr>
635
+ `
616
636
  : nothing}
617
- ${rowTemplates}
618
- ${suggestedKeyButtons.length > 0
637
+ ${rowTemplates}
638
+ ${suggestedKeyButtons.length > 0
619
639
  ? html `
620
- <div class="json-add-row">${suggestedKeyButtons}</div>
621
- `
640
+ <tr>
641
+ <td colspan="3">
642
+ <div class="json-add-row">${suggestedKeyButtons}</div>
643
+ </td>
644
+ </tr>
645
+ `
622
646
  : nothing}
623
- ${arbitraryAddRow}
624
- </div>
647
+ ${arbitraryAddRow}
648
+ </tbody>
649
+ </table>
625
650
  `;
626
651
  }
627
- function renderArrayGroup(path, value, schema, onDelete) {
652
+ function renderArrayGroup(path, value, schema) {
628
653
  const pathKey = pathToKey(path);
654
+ const isRoot = path.length === 0;
629
655
  const newItemSchema = getNewItemSchema(schema, value.length, resolveContext);
630
656
  const allowedItemTypes = getAllowedJsonTypes(newItemSchema, resolveContext);
631
657
  const rowTemplates = value.map((item, index) => {
@@ -641,28 +667,43 @@ export const ViraJsonForm = defineViraElement()({
641
667
  : () => {
642
668
  emitDeleteAt(childPath);
643
669
  };
670
+ if (isChildNested) {
671
+ return html `
672
+ <tr class="json-row-nested">
673
+ <td colspan="3">
674
+ <div class="json-row-nested-header">
675
+ <span class="json-row-label">
676
+ [${index}]
677
+ <span class="json-type-tag">
678
+ : ${getNestedTypeLabel(childSchema, item)}
679
+ </span>
680
+ </span>
681
+ ${childOnDelete ? renderDeleteButton(childOnDelete) : nothing}
682
+ </div>
683
+ ${renderValue(childPath, item, childSchema)}
684
+ </td>
685
+ </tr>
686
+ `;
687
+ }
644
688
  return html `
645
- <div
646
- class="json-row ${isChildNested ? 'json-row-nested' : 'json-row-primitive'}"
647
- >
648
- <span class="json-row-label">[${index}]</span>
649
- <span class="json-row-editor">
650
- ${renderValue(childPath, item, childSchema, isChildNested ? childOnDelete : undefined)}
651
- </span>
652
- <span class="json-row-delete">
653
- ${!isChildNested && childOnDelete
654
- ? renderDeleteButton(childOnDelete)
655
- : nothing}
656
- </span>
657
- </div>
689
+ <tr class="json-row-primitive">
690
+ <td class="json-row-label">[${index}]</td>
691
+ <td class="json-row-editor">
692
+ ${renderValue(childPath, item, childSchema)}
693
+ </td>
694
+ <td class="json-row-delete">
695
+ ${childOnDelete ? renderDeleteButton(childOnDelete) : nothing}
696
+ </td>
697
+ </tr>
658
698
  `;
659
699
  });
660
- const title = getSchemaTitle(schema, resolveContext) || 'array';
661
700
  const addRow = isDisabled
662
701
  ? nothing
663
702
  : html `
664
- <div class="json-add-row">
665
- ${renderArrayAddControl({
703
+ <tr>
704
+ <td colspan="3">
705
+ <div class="json-add-row">
706
+ ${renderArrayAddControl({
666
707
  pathKey,
667
708
  allowedTypes: allowedItemTypes,
668
709
  onAdd: (newValue) => {
@@ -672,32 +713,36 @@ export const ViraJsonForm = defineViraElement()({
672
713
  ], newValue);
673
714
  },
674
715
  })}
675
- </div>
716
+ </div>
717
+ </td>
718
+ </tr>
676
719
  `;
677
720
  return html `
678
- <div class="json-group">
679
- <div class="json-group-header">
680
- <span class="json-group-header-title">${title}</span>
681
- ${onDelete ? renderDeleteButton(onDelete) : nothing}
682
- </div>
683
- ${rowTemplates.length === 0
721
+ <table class="json-group ${isRoot ? '' : 'json-group-nested'}">
722
+ <tbody>
723
+ ${rowTemplates.length === 0
684
724
  ? html `
685
- <span class="json-empty-note">(empty array)</span>
686
- `
725
+ <tr>
726
+ <td colspan="3">
727
+ <span class="json-empty-note">(empty array)</span>
728
+ </td>
729
+ </tr>
730
+ `
687
731
  : nothing}
688
- ${rowTemplates} ${addRow}
689
- </div>
732
+ ${rowTemplates} ${addRow}
733
+ </tbody>
734
+ </table>
690
735
  `;
691
736
  }
692
- function renderValue(path, value, schema, onDelete) {
737
+ function renderValue(path, value, schema) {
693
738
  const concreteType = getJsonType(value);
694
739
  const allowedTypes = getAllowedJsonTypes(schema, resolveContext);
695
740
  const narrowedSchema = pickBranchForType(schema, concreteType, resolveContext);
696
741
  if (check.isArray(value)) {
697
- return renderArrayGroup(path, value, narrowedSchema, onDelete);
742
+ return renderArrayGroup(path, value, narrowedSchema);
698
743
  }
699
744
  else if (check.isObject(value)) {
700
- return renderObjectGroup(path, value, narrowedSchema, onDelete);
745
+ return renderObjectGroup(path, value, narrowedSchema);
701
746
  }
702
747
  const editor = renderPrimitive(path, value, narrowedSchema);
703
748
  const showSwitcher = !isDisabled &&
@@ -742,8 +787,10 @@ export const ViraJsonForm = defineViraElement()({
742
787
  })}
743
788
  title=${state.showRaw ? 'Show rich editor' : 'Show raw JSON'}
744
789
  ${listen('click', () => {
790
+ const goingToRaw = !state.showRaw;
791
+ host.style.minWidth = goingToRaw ? `${host.offsetWidth}px` : '';
745
792
  updateState({
746
- showRaw: !state.showRaw,
793
+ showRaw: goingToRaw,
747
794
  rawDraft: undefined,
748
795
  rawError: undefined,
749
796
  });
@@ -755,14 +802,15 @@ export const ViraJsonForm = defineViraElement()({
755
802
  const rawText = state.rawDraft ?? JSON.stringify(inputs.value, undefined, 4);
756
803
  return html `
757
804
  ${toolbarTemplate}
758
- <textarea
805
+ <${ViraTextArea.assign({
806
+ value: rawText,
807
+ disabled: isDisabled,
808
+ disableBrowserHelps: true,
809
+ rows: 12,
810
+ })}
759
811
  class="json-raw-textarea"
760
- spellcheck="false"
761
- ?disabled=${isDisabled}
762
- .value=${rawText}
763
- ${listen('input', (event) => {
764
- const textarea = extractEventTarget(event, HTMLTextAreaElement);
765
- const text = textarea.value;
812
+ ${listen(ViraTextArea.events.valueChange, (event) => {
813
+ const text = event.detail;
766
814
  const parsed = wrapInTry(() => JSON.parse(text));
767
815
  if (parsed instanceof Error) {
768
816
  updateState({
@@ -778,7 +826,7 @@ export const ViraJsonForm = defineViraElement()({
778
826
  emitRoot(parsed);
779
827
  }
780
828
  })}
781
- ></textarea>
829
+ ></${ViraTextArea}>
782
830
  ${state.rawError
783
831
  ? html `
784
832
  <${ViraError}>${state.rawError}</${ViraError}>
@@ -803,7 +851,7 @@ export const ViraJsonForm = defineViraElement()({
803
851
  `;
804
852
  }
805
853
  return html `
806
- ${toolbarTemplate} ${renderValue([], inputs.value, inputs.schema, undefined)}
854
+ ${toolbarTemplate} ${renderValue([], inputs.value, inputs.schema)}
807
855
  `;
808
856
  },
809
857
  });
@@ -112,7 +112,7 @@ export const ViraLink = defineViraElement()({
112
112
  else {
113
113
  const linkUrl = inputs.link
114
114
  ? inputs.link.url
115
- : inputs.route.router.createRouteUrl(inputs.route.route);
115
+ : inputs.route.router.createRouteUrl(inputs.route.route).url;
116
116
  /** Noopener and noreferrer are needed for security reasons, do not remove! */
117
117
  return html `
118
118
  <a
@@ -56,6 +56,7 @@ export const ViraTextArea = defineViraElement()({
56
56
 
57
57
  textarea {
58
58
  ${noNativeFormStyles};
59
+ overscroll-behavior: contain;
59
60
  font: inherit;
60
61
  cursor: text;
61
62
  width: 100%;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * A plus icon.
3
+ *
4
+ * @category Icon
5
+ * @category SVG
6
+ * @see https://electrovir.github.io/vira/book/icons/plus16icon
7
+ */
8
+ export declare const Plus16Icon: import("../../icon-svg.js").ViraIconSvg;
@@ -1,19 +1,19 @@
1
1
  import { html } from 'element-vir';
2
- import { viraIconCssVars } from '../icon-css-vars.js';
3
- import { defineIcon } from '../icon-svg.js';
2
+ import { viraIconCssVars } from '../../icon-css-vars.js';
3
+ import { defineIcon } from '../../icon-svg.js';
4
4
  /**
5
5
  * A plus icon.
6
6
  *
7
7
  * @category Icon
8
8
  * @category SVG
9
- * @see https://electrovir.github.io/vira/book/icons/plus24icon
9
+ * @see https://electrovir.github.io/vira/book/icons/plus16icon
10
10
  */
11
- export const Plus24Icon = defineIcon({
12
- name: 'Plus24Icon',
11
+ export const Plus16Icon = defineIcon({
12
+ name: 'Plus16Icon',
13
13
  svgTemplate: html `
14
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24">
14
+ <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16">
15
15
  <path
16
- d="M12 5v14M5 12h14"
16
+ d="M8 3v10M3 8h10"
17
17
  fill="none"
18
18
  stroke=${viraIconCssVars['vira-icon-stroke-color'].value}
19
19
  stroke-width=${viraIconCssVars['vira-icon-stroke-width'].value}
@@ -8,6 +8,7 @@ export * from './icon-svgs/16/chevron-down-16.icon.js';
8
8
  export * from './icon-svgs/16/chevron-up-16.icon.js';
9
9
  export * from './icon-svgs/16/dash-16.icon.js';
10
10
  export * from './icon-svgs/16/element-16.icon.js';
11
+ export * from './icon-svgs/16/plus-16.icon.js';
11
12
  export * from './icon-svgs/16/upload-16.icon.js';
12
13
  export * from './icon-svgs/16/x-16.icon.js';
13
14
  export * from './icon-svgs/24/arrow-down-24.icon.js';
@@ -100,6 +101,7 @@ export declare const allIconsByName: {
100
101
  readonly Moon24Icon: import("./icon-svg.js").ViraIconSvg;
101
102
  readonly Options24Icon: import("./icon-svg.js").ViraIconSvg;
102
103
  readonly Pencil24Icon: import("./icon-svg.js").ViraIconSvg;
104
+ readonly Plus16Icon: import("./icon-svg.js").ViraIconSvg;
103
105
  readonly Plus24Icon: import("./icon-svg.js").ViraIconSvg;
104
106
  readonly Printer24Icon: import("./icon-svg.js").ViraIconSvg;
105
107
  readonly Shield24Icon: import("./icon-svg.js").ViraIconSvg;
@@ -189,6 +191,7 @@ export declare const all16IconsByName: {
189
191
  readonly ChevronUp16Icon: import("./icon-svg.js").ViraIconSvg;
190
192
  readonly Dash16Icon: import("./icon-svg.js").ViraIconSvg;
191
193
  readonly Element16Icon: import("./icon-svg.js").ViraIconSvg;
194
+ readonly Plus16Icon: import("./icon-svg.js").ViraIconSvg;
192
195
  readonly Upload16Icon: import("./icon-svg.js").ViraIconSvg;
193
196
  readonly X16Icon: import("./icon-svg.js").ViraIconSvg;
194
197
  };
@@ -3,6 +3,7 @@ import { ChevronDown16Icon } from './icon-svgs/16/chevron-down-16.icon.js';
3
3
  import { ChevronUp16Icon } from './icon-svgs/16/chevron-up-16.icon.js';
4
4
  import { Dash16Icon } from './icon-svgs/16/dash-16.icon.js';
5
5
  import { Element16Icon } from './icon-svgs/16/element-16.icon.js';
6
+ import { Plus16Icon } from './icon-svgs/16/plus-16.icon.js';
6
7
  import { Upload16Icon } from './icon-svgs/16/upload-16.icon.js';
7
8
  import { X16Icon } from './icon-svgs/16/x-16.icon.js';
8
9
  import { ArrowDown24Icon } from './icon-svgs/24/arrow-down-24.icon.js';
@@ -64,6 +65,7 @@ export * from './icon-svgs/16/chevron-down-16.icon.js';
64
65
  export * from './icon-svgs/16/chevron-up-16.icon.js';
65
66
  export * from './icon-svgs/16/dash-16.icon.js';
66
67
  export * from './icon-svgs/16/element-16.icon.js';
68
+ export * from './icon-svgs/16/plus-16.icon.js';
67
69
  export * from './icon-svgs/16/upload-16.icon.js';
68
70
  export * from './icon-svgs/16/x-16.icon.js';
69
71
  export * from './icon-svgs/24/arrow-down-24.icon.js';
@@ -156,6 +158,7 @@ export const allIconsByName = {
156
158
  Moon24Icon,
157
159
  Options24Icon,
158
160
  Pencil24Icon,
161
+ Plus16Icon,
159
162
  Plus24Icon,
160
163
  Printer24Icon,
161
164
  Shield24Icon,
@@ -245,6 +248,7 @@ export const all16IconsByName = {
245
248
  ChevronUp16Icon,
246
249
  Dash16Icon,
247
250
  Element16Icon,
251
+ Plus16Icon,
248
252
  Upload16Icon,
249
253
  X16Icon,
250
254
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vira",
3
- "version": "31.18.0",
3
+ "version": "31.18.2",
4
4
  "description": "A simple and highly versatile design system using element-vir.",
5
5
  "keywords": [
6
6
  "design",
@@ -38,35 +38,35 @@
38
38
  "test:docs": "virmator docs check"
39
39
  },
40
40
  "dependencies": {
41
- "@augment-vir/assert": "^31.68.2",
42
- "@augment-vir/common": "^31.68.2",
43
- "@augment-vir/web": "^31.68.2",
41
+ "@augment-vir/assert": "^31.69.0",
42
+ "@augment-vir/common": "^31.69.0",
43
+ "@augment-vir/web": "^31.69.0",
44
44
  "@electrovir/color": "^1.7.9",
45
- "date-vir": "^8.2.1",
45
+ "date-vir": "^8.3.2",
46
46
  "device-navigation": "^4.5.5",
47
47
  "json-schema-to-ts": "^3.1.1",
48
48
  "lit-css-vars": "^3.6.2",
49
49
  "observavir": "^2.3.2",
50
50
  "page-active": "^1.0.3",
51
- "spa-router-vir": "^6.4.1",
52
- "type-fest": "^5.5.0",
51
+ "spa-router-vir": "^6.5.0",
52
+ "type-fest": "^5.6.0",
53
53
  "typed-event-target": "^4.3.0"
54
54
  },
55
55
  "devDependencies": {
56
- "@augment-vir/test": "^31.68.2",
56
+ "@augment-vir/test": "^31.69.0",
57
57
  "@web/dev-server-esbuild": "^1.0.5",
58
58
  "@web/test-runner": "^0.20.2",
59
59
  "@web/test-runner-commands": "^0.9.0",
60
60
  "@web/test-runner-playwright": "^0.11.1",
61
61
  "@web/test-runner-visual-regression": "^0.10.0",
62
- "esbuild": "^0.27.4",
62
+ "esbuild": "^0.28.0",
63
63
  "istanbul-smart-text-reporter": "^1.1.5",
64
- "lucide-static": "^1.7.0",
65
- "markdown-code-example-inserter": "^3.0.3",
64
+ "lucide-static": "^1.14.0",
65
+ "markdown-code-example-inserter": "^3.0.5",
66
66
  "theme-vir": "^28.25.0",
67
- "typedoc": "^0.28.18",
67
+ "typedoc": "^0.28.19",
68
68
  "typescript": "5.9.3",
69
- "vite": "^8.0.3",
69
+ "vite": "^8.0.10",
70
70
  "vite-tsconfig-paths": "^6.1.1"
71
71
  },
72
72
  "peerDependencies": {
@@ -1,8 +0,0 @@
1
- /**
2
- * A plus icon.
3
- *
4
- * @category Icon
5
- * @category SVG
6
- * @see https://electrovir.github.io/vira/book/icons/plus24icon
7
- */
8
- export declare const Plus24Icon: import("../icon-svg.js").ViraIconSvg;