vira 31.17.1 → 31.18.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.
@@ -22,3 +22,4 @@ export * from './vira-progress.element.js';
22
22
  export * from './vira-select.element.js';
23
23
  export * from './vira-tabs.element.js';
24
24
  export * from './vira-tag.element.js';
25
+ export * from './vira-text-area.element.js';
@@ -22,3 +22,4 @@ export * from './vira-progress.element.js';
22
22
  export * from './vira-select.element.js';
23
23
  export * from './vira-tabs.element.js';
24
24
  export * from './vira-tag.element.js';
25
+ export * from './vira-text-area.element.js';
@@ -5,6 +5,7 @@ import { applyRequiredLabel, areFormFieldsValid, ViraFormFieldType, } from '../u
5
5
  import { ViraCheckbox } from './vira-checkbox.element.js';
6
6
  import { ViraInput, ViraInputType } from './vira-input.element.js';
7
7
  import { ViraSelect } from './vira-select.element.js';
8
+ import { ViraTextArea } from './vira-text-area.element.js';
8
9
  /**
9
10
  * A form element.
10
11
  *
@@ -95,6 +96,28 @@ export const ViraForm = defineViraElement()({
95
96
  ></${ViraSelect}>
96
97
  `;
97
98
  }
99
+ else if (field.type === ViraFormFieldType.TextArea) {
100
+ return html `
101
+ <${ViraTextArea.assign({
102
+ value: field.value || '',
103
+ disabled: inputs.isDisabled || field.isDisabled,
104
+ hasError: field.hasError,
105
+ label: applyRequiredLabel(field.label, !!field.isRequired && !inputs.hideRequiredMarkers),
106
+ placeholder: field.placeholder,
107
+ rows: field.rows,
108
+ preventResize: field.preventResize,
109
+ })}
110
+ ${field.testId ? testId(field.testId) : nothing}
111
+ ${listen(ViraTextArea.events.valueChange, (event) => {
112
+ dispatch(new events.valueChange({
113
+ key,
114
+ ...field,
115
+ value: event.detail,
116
+ }));
117
+ })}
118
+ ></${ViraTextArea}>
119
+ `;
120
+ }
98
121
  else if (field.type === ViraFormFieldType.Number) {
99
122
  return html `
100
123
  <${ViraInput.assign({
@@ -17,6 +17,8 @@ export declare const ViraJsonForm: import("element-vir").DeclarativeElementDefin
17
17
  pendingTypes: Readonly<Record<string, ViraJsonType>>;
18
18
  pendingArrayValues: Readonly<Record<string, JsonValue>>;
19
19
  showRaw: boolean;
20
+ rawDraft: string | undefined;
21
+ rawError: string | undefined;
20
22
  }, {
21
23
  valueChange: import("element-vir").DefineEvent<JsonValue>;
22
24
  }, "vira-json-form-", "vira-json-form-", readonly [], readonly []>;
@@ -1,5 +1,6 @@
1
1
  import { assertWrap, check } from '@augment-vir/assert';
2
- import { omitObjectKeys } from '@augment-vir/common';
2
+ import { omitObjectKeys, wrapInTry } from '@augment-vir/common';
3
+ import { extractEventTarget } from '@augment-vir/web';
3
4
  import { css, defineElementEvent, html, listen, nothing } from 'element-vir';
4
5
  import { lucideIcons, X16Icon } from '../icons/index.js';
5
6
  import { viraFontCssVars } from '../styles/font.js';
@@ -29,6 +30,8 @@ export const ViraJsonForm = defineViraElement()({
29
30
  pendingTypes: {},
30
31
  pendingArrayValues: {},
31
32
  showRaw: false,
33
+ rawDraft: undefined,
34
+ rawError: undefined,
32
35
  };
33
36
  },
34
37
  styles: css `
@@ -45,18 +48,24 @@ export const ViraJsonForm = defineViraElement()({
45
48
  justify-content: flex-end;
46
49
  }
47
50
 
48
- .json-raw-pre {
51
+ .json-raw-textarea {
49
52
  margin: 0;
50
53
  padding: 10px 12px;
51
54
  border: 1px solid ${viraFormCssVars['vira-form-border-color'].value};
52
55
  border-radius: ${viraFormCssVars['vira-form-wrapper-radius'].value};
53
56
  background-color: ${viraFormCssVars['vira-form-background-color'].value};
57
+ color: ${viraFormCssVars['vira-form-foreground-color'].value};
54
58
  font-family: ${viraFontCssVars['vira-monospace'].value};
55
59
  font-size: ${viraFormCssVars['vira-form-small-text-size'].value};
56
- white-space: pre-wrap;
57
- word-break: break-word;
58
- overflow-x: auto;
59
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};
60
69
  }
61
70
 
62
71
  .json-validation-errors {
@@ -78,6 +87,7 @@ export const ViraJsonForm = defineViraElement()({
78
87
  border: 1px solid ${viraFormCssVars['vira-form-border-color'].value};
79
88
  border-radius: ${viraFormCssVars['vira-form-wrapper-radius'].value};
80
89
  background-color: ${viraFormCssVars['vira-form-background-color'].value};
90
+ box-sizing: border-box;
81
91
  }
82
92
 
83
93
  .json-group-header {
@@ -103,7 +113,9 @@ export const ViraJsonForm = defineViraElement()({
103
113
  }
104
114
 
105
115
  .json-row-nested {
106
- align-items: flex-start;
116
+ flex-direction: column;
117
+ align-items: stretch;
118
+ gap: 4px;
107
119
  }
108
120
 
109
121
  .json-row-label {
@@ -113,10 +125,6 @@ export const ViraJsonForm = defineViraElement()({
113
125
  word-break: break-word;
114
126
  }
115
127
 
116
- .json-row-nested .json-row-label {
117
- padding-top: 10px;
118
- }
119
-
120
128
  .json-row-editor {
121
129
  flex-grow: 1;
122
130
  min-width: 0;
@@ -136,10 +144,6 @@ export const ViraJsonForm = defineViraElement()({
136
144
  justify-content: center;
137
145
  }
138
146
 
139
- .json-row-nested .json-row-delete {
140
- padding-top: 4px;
141
- }
142
-
143
147
  .json-value-with-switcher {
144
148
  display: flex;
145
149
  align-items: center;
@@ -191,7 +195,7 @@ export const ViraJsonForm = defineViraElement()({
191
195
  font-size: ${viraFormCssVars['vira-form-small-text-size'].value};
192
196
  }
193
197
  `,
194
- render({ inputs, state, dispatch, events, updateState }) {
198
+ render({ inputs, state, dispatch, events, updateState, host }) {
195
199
  const isDisabled = !!inputs.isDisabled;
196
200
  const resolveContext = createResolveContext(inputs.schema);
197
201
  function jsonPrimitiveToString(entry) {
@@ -733,17 +737,50 @@ export const ViraJsonForm = defineViraElement()({
733
737
  })}
734
738
  title=${state.showRaw ? 'Show rich editor' : 'Show raw JSON'}
735
739
  ${listen('click', () => {
740
+ const goingToRaw = !state.showRaw;
741
+ host.style.minWidth = goingToRaw ? `${host.offsetWidth}px` : '';
736
742
  updateState({
737
- showRaw: !state.showRaw,
743
+ showRaw: goingToRaw,
744
+ rawDraft: undefined,
745
+ rawError: undefined,
738
746
  });
739
747
  })}
740
748
  ></${ViraButton}>
741
749
  </div>
742
750
  `;
743
751
  if (state.showRaw) {
752
+ const rawText = state.rawDraft ?? JSON.stringify(inputs.value, undefined, 4);
744
753
  return html `
745
754
  ${toolbarTemplate}
746
- <pre class="json-raw-pre">${JSON.stringify(inputs.value, undefined, 4)}</pre>
755
+ <textarea
756
+ class="json-raw-textarea"
757
+ spellcheck="false"
758
+ ?disabled=${isDisabled}
759
+ .value=${rawText}
760
+ ${listen('input', (event) => {
761
+ const textarea = extractEventTarget(event, HTMLTextAreaElement);
762
+ const text = textarea.value;
763
+ const parsed = wrapInTry(() => JSON.parse(text));
764
+ if (parsed instanceof Error) {
765
+ updateState({
766
+ rawDraft: text,
767
+ rawError: parsed.message,
768
+ });
769
+ }
770
+ else {
771
+ updateState({
772
+ rawDraft: text,
773
+ rawError: undefined,
774
+ });
775
+ emitRoot(parsed);
776
+ }
777
+ })}
778
+ ></textarea>
779
+ ${state.rawError
780
+ ? html `
781
+ <${ViraError}>${state.rawError}</${ViraError}>
782
+ `
783
+ : nothing}
747
784
  `;
748
785
  }
749
786
  const validationErrors = validateAgainstSchema(inputs.value, inputs.schema);
@@ -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
@@ -0,0 +1,47 @@
1
+ import { type PartialWithUndefined } from '@augment-vir/common';
2
+ /**
3
+ * A multi-line text area element with all listeners properly attached. Mirrors the look and feel of
4
+ * {@link ViraInput} but for multi-line text input.
5
+ *
6
+ * @category Input
7
+ * @category Elements
8
+ * @see https://electrovir.github.io/vira/book/elements/vira-text-area
9
+ */
10
+ export declare const ViraTextArea: import("element-vir").DeclarativeElementDefinition<"vira-text-area", PartialWithUndefined<{
11
+ /** A label that is shown above the text area, if provided. */
12
+ label: string;
13
+ /** If true, applies error styling. */
14
+ hasError: boolean;
15
+ /** Number of visible text rows. Defaults to 4. */
16
+ rows: number;
17
+ /** If true, blocks the user's ability to resize the text area. */
18
+ preventResize: boolean;
19
+ }> & {
20
+ value: string;
21
+ } & PartialWithUndefined<{
22
+ placeholder: string;
23
+ disabled: boolean;
24
+ allowedInputs: string | RegExp;
25
+ blockedInputs: string | RegExp;
26
+ disableBrowserHelps: boolean;
27
+ fitText: boolean;
28
+ attributePassthrough: import("element-vir").AttributeValues;
29
+ }>, {
30
+ /**
31
+ * Used to couple the label and text area together. This is not applied if no label is
32
+ * provided.
33
+ */
34
+ randomId: string;
35
+ }, {
36
+ /**
37
+ * Fires whenever a user input created a new value. Does not fire if all input letters are
38
+ * filtered out due to input restrictions.
39
+ */
40
+ valueChange: import("element-vir").DefineEvent<string>;
41
+ /**
42
+ * Fires when inputs are blocked. Useful for showing warnings or error messages to inform
43
+ * the user why their input did not propagate if it was blocked. This does not fire for text
44
+ * that was blocked out of programmatic "value" property assignments.
45
+ */
46
+ inputBlocked: import("element-vir").DefineEvent<string>;
47
+ }, "vira-text-area-disabled" | "vira-text-area-error" | "vira-text-area-prevent-resize", "vira-text-area-padding-horizontal" | "vira-text-area-padding-vertical", readonly [], readonly []>;
@@ -0,0 +1,201 @@
1
+ import { randomString } from '@augment-vir/common';
2
+ import { attributes, css, defineElementEvent, html, ifDefined, listen } from 'element-vir';
3
+ import { createFocusStyles } from '../styles/focus.js';
4
+ import { viraFormCssVars } from '../styles/form-styles.js';
5
+ import { viraDisabledStyles } from '../styles/index.js';
6
+ import { noNativeFormStyles } from '../styles/native-styles.js';
7
+ import { defineViraElement } from '../util/define-vira-element.js';
8
+ import { filterTextInputValue, textInputListener, } from '../util/shared-text-input-logic.js';
9
+ /**
10
+ * A multi-line text area element with all listeners properly attached. Mirrors the look and feel of
11
+ * {@link ViraInput} but for multi-line text input.
12
+ *
13
+ * @category Input
14
+ * @category Elements
15
+ * @see https://electrovir.github.io/vira/book/elements/vira-text-area
16
+ */
17
+ export const ViraTextArea = defineViraElement()({
18
+ tagName: 'vira-text-area',
19
+ cssVars: {
20
+ 'vira-text-area-padding-horizontal': '10px',
21
+ 'vira-text-area-padding-vertical': '6px',
22
+ },
23
+ styles: ({ hostClasses, cssVars }) => css `
24
+ :host {
25
+ position: relative;
26
+ display: inline-flex;
27
+ width: 320px;
28
+ box-sizing: border-box;
29
+ color: ${viraFormCssVars['vira-form-foreground-color'].value};
30
+ }
31
+
32
+ label {
33
+ display: flex;
34
+ flex-direction: column;
35
+ justify-content: flex-start;
36
+ gap: 2px;
37
+ width: 100%;
38
+ max-width: 100%;
39
+ cursor: text;
40
+
41
+ & .text-area-label {
42
+ font-weight: ${viraFormCssVars['vira-form-label-font-weight'].value};
43
+ text-align: left;
44
+ flex-shrink: 0;
45
+ flex-wrap: wrap;
46
+ }
47
+ }
48
+
49
+ .text-area-wrapper {
50
+ position: relative;
51
+ display: inline-flex;
52
+ width: 100%;
53
+ max-width: 100%;
54
+ box-sizing: border-box;
55
+ }
56
+
57
+ textarea {
58
+ ${noNativeFormStyles};
59
+ font: inherit;
60
+ cursor: text;
61
+ width: 100%;
62
+ box-sizing: border-box;
63
+ padding: ${cssVars['vira-text-area-padding-vertical'].value}
64
+ ${cssVars['vira-text-area-padding-horizontal'].value};
65
+ border-radius: ${viraFormCssVars['vira-form-radius'].value};
66
+ background-color: ${viraFormCssVars['vira-form-background-color'].value};
67
+ border: 1px solid ${viraFormCssVars['vira-form-border-color'].value};
68
+ color: inherit;
69
+ resize: vertical;
70
+ outline: none;
71
+
72
+ &::placeholder {
73
+ color: ${viraFormCssVars['vira-form-placeholder-color'].value};
74
+ }
75
+
76
+ &::selection {
77
+ background: ${viraFormCssVars['vira-form-text-selection-color'].value};
78
+ }
79
+
80
+ &:focus:focus-visible:not([disabled]) ~ .focus-border {
81
+ ${createFocusStyles({
82
+ elementBorderSize: '1px',
83
+ noNesting: true,
84
+ })}
85
+ }
86
+ }
87
+
88
+ .border-style {
89
+ position: absolute;
90
+ top: 0;
91
+ left: 0;
92
+ width: 100%;
93
+ height: 100%;
94
+ border-radius: ${viraFormCssVars['vira-form-radius'].value};
95
+ z-index: 0;
96
+ pointer-events: none;
97
+ }
98
+
99
+ ${hostClasses['vira-text-area-prevent-resize'].selector} textarea {
100
+ resize: none;
101
+ }
102
+
103
+ ${hostClasses['vira-text-area-error'].selector} textarea {
104
+ border-color: ${viraFormCssVars['vira-form-error-color'].value};
105
+ }
106
+
107
+ ${hostClasses['vira-text-area-disabled'].selector} {
108
+ cursor: not-allowed;
109
+
110
+ & * {
111
+ cursor: not-allowed;
112
+ }
113
+
114
+ & > * {
115
+ ${viraDisabledStyles};
116
+ }
117
+
118
+ & .focus-border {
119
+ display: none;
120
+ }
121
+ }
122
+ `,
123
+ events: {
124
+ /**
125
+ * Fires whenever a user input created a new value. Does not fire if all input letters are
126
+ * filtered out due to input restrictions.
127
+ */
128
+ valueChange: defineElementEvent(),
129
+ /**
130
+ * Fires when inputs are blocked. Useful for showing warnings or error messages to inform
131
+ * the user why their input did not propagate if it was blocked. This does not fire for text
132
+ * that was blocked out of programmatic "value" property assignments.
133
+ */
134
+ inputBlocked: defineElementEvent(),
135
+ },
136
+ state() {
137
+ return {
138
+ /**
139
+ * Used to couple the label and text area together. This is not applied if no label is
140
+ * provided.
141
+ */
142
+ randomId: randomString(32),
143
+ };
144
+ },
145
+ hostClasses: {
146
+ 'vira-text-area-disabled': ({ inputs }) => !!inputs.disabled,
147
+ 'vira-text-area-error': ({ inputs }) => !!inputs.hasError,
148
+ 'vira-text-area-prevent-resize': ({ inputs }) => !!inputs.preventResize || !!inputs.disabled,
149
+ },
150
+ render({ inputs, dispatch, state, events }) {
151
+ const { filtered: filteredValue } = filterTextInputValue({
152
+ value: inputs.value,
153
+ allowed: inputs.allowedInputs,
154
+ blocked: inputs.blockedInputs,
155
+ });
156
+ const textAreaTemplate = html `
157
+ <span class="text-area-wrapper">
158
+ <textarea
159
+ id=${ifDefined(inputs.label ? state.randomId : undefined)}
160
+ aria-label=${ifDefined(inputs.label || undefined)}
161
+ rows=${inputs.rows ?? 4}
162
+ ?disabled=${inputs.disabled}
163
+ autocomplete=${ifDefined(inputs.disableBrowserHelps ? 'off' : undefined)}
164
+ autocorrect=${ifDefined(inputs.disableBrowserHelps ? 'off' : undefined)}
165
+ autocapitalize=${ifDefined(inputs.disableBrowserHelps ? 'off' : undefined)}
166
+ spellcheck=${ifDefined(inputs.disableBrowserHelps ? 'false' : undefined)}
167
+ placeholder=${ifDefined(inputs.placeholder || undefined)}
168
+ .value=${filteredValue}
169
+ ${listen('input', (event) => {
170
+ textInputListener({
171
+ inputs,
172
+ previousValue: filteredValue,
173
+ event,
174
+ elementConstructor: HTMLTextAreaElement,
175
+ inputBlockedCallback(blockedInput) {
176
+ dispatch(new events.inputBlocked(blockedInput));
177
+ },
178
+ newValueCallback(newValue) {
179
+ dispatch(new events.valueChange(newValue));
180
+ },
181
+ });
182
+ })}
183
+ ${attributes(inputs.attributePassthrough)}
184
+ ></textarea>
185
+
186
+ <div class="border-style focus-border"></div>
187
+ </span>
188
+ `;
189
+ if (inputs.label) {
190
+ return html `
191
+ <label for=${state.randomId}>
192
+ <span class="text-area-label">${inputs.label}</span>
193
+ ${textAreaTemplate}
194
+ </label>
195
+ `;
196
+ }
197
+ else {
198
+ return textAreaTemplate;
199
+ }
200
+ },
201
+ });
@@ -53,11 +53,16 @@ export declare function filterTextInputValue(inputs: IsAllowedInputs): {
53
53
  *
54
54
  * @category Internal
55
55
  */
56
- export declare function textInputListener({ inputs, previousValue, event, inputBlockedCallback, newValueCallback, }: {
56
+ export declare function textInputListener({ inputs, previousValue, event, elementConstructor, inputBlockedCallback, newValueCallback, }: {
57
57
  inputs: SharedTextInputElementInputs;
58
58
  /** The value of the input element before this listener fired. */
59
59
  previousValue: string;
60
60
  event: Event;
61
+ /**
62
+ * The constructor for the underlying native element. Defaults to `HTMLInputElement`, but can be
63
+ * set to `HTMLTextAreaElement` for textarea-based elements.
64
+ */
65
+ elementConstructor?: typeof HTMLInputElement | typeof HTMLTextAreaElement | undefined;
61
66
  inputBlockedCallback: (blockedInput: string) => void;
62
67
  newValueCallback: (newValue: string) => void;
63
68
  }): void;
@@ -72,8 +72,8 @@ export function filterTextInputValue(inputs) {
72
72
  *
73
73
  * @category Internal
74
74
  */
75
- export function textInputListener({ inputs, previousValue, event, inputBlockedCallback, newValueCallback, }) {
76
- const inputElement = extractEventTarget(event, HTMLInputElement);
75
+ export function textInputListener({ inputs, previousValue, event, elementConstructor, inputBlockedCallback, newValueCallback, }) {
76
+ const inputElement = extractEventTarget(event, elementConstructor || HTMLInputElement);
77
77
  /**
78
78
  * This is usually a single character, but can be a bunch of characters in some circumstances.
79
79
  * For example, when a bunch of characters are pasted, this will be the entire pasted contents.
@@ -17,7 +17,8 @@ export declare enum ViraFormFieldType {
17
17
  Email = "email",
18
18
  Number = "number",
19
19
  Select = "select",
20
- Checkbox = "checkbox"
20
+ Checkbox = "checkbox",
21
+ TextArea = "text-area"
21
22
  }
22
23
  /**
23
24
  * {@link ViraFormField} properties that are shared between all field types.
@@ -85,6 +86,13 @@ export type ViraFormField = ({
85
86
  min: number;
86
87
  max: number;
87
88
  step: number;
89
+ }> & CommonViraFormFields) | ({
90
+ type: ViraFormFieldType.TextArea;
91
+ value: string | undefined;
92
+ } & PartialWithUndefined<{
93
+ placeholder: string;
94
+ rows: number;
95
+ preventResize: boolean;
88
96
  }> & CommonViraFormFields);
89
97
  /**
90
98
  * A collection of form fields for `ViraForm`.
@@ -18,6 +18,7 @@ export var ViraFormFieldType;
18
18
  ViraFormFieldType["Number"] = "number";
19
19
  ViraFormFieldType["Select"] = "select";
20
20
  ViraFormFieldType["Checkbox"] = "checkbox";
21
+ ViraFormFieldType["TextArea"] = "text-area";
21
22
  })(ViraFormFieldType || (ViraFormFieldType = {}));
22
23
  /**
23
24
  * Appends a `'*'` to a label if it exist sand if it is required.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vira",
3
- "version": "31.17.1",
3
+ "version": "31.18.1",
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": {