@studiometa/ui 1.0.0-rc.7 → 1.0.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.
@@ -1,9 +1,13 @@
1
1
  import type { Base } from '@studiometa/js-toolkit';
2
- export type Modifiers = 'prevent' | 'stop' | 'once' | 'passive' | 'capture';
2
+ export type Modifiers = 'prevent' | 'stop' | 'once' | 'passive' | 'capture' | 'debounce';
3
3
  export declare class ActionEvent<T extends Base> {
4
4
  static modifierSeparator: string;
5
5
  static targetSeparator: string;
6
6
  static effectSeparator: string;
7
+ /**
8
+ * Timer for debouncing event handling.
9
+ */
10
+ private debounceTimer?;
7
11
  /**
8
12
  * The Action instance.
9
13
  */
@@ -16,6 +20,10 @@ export declare class ActionEvent<T extends Base> {
16
20
  * The modifiers to apply to the event.
17
21
  */
18
22
  modifiers: Modifiers[];
23
+ /**
24
+ * The debounce delay in milliseconds.
25
+ */
26
+ debounceDelay: number;
19
27
  /**
20
28
  * Target definition.
21
29
  * Ex: `Target Target(.selector)`.
@@ -44,6 +52,10 @@ export declare class ActionEvent<T extends Base> {
44
52
  * Handle the defined event and trigger the effect for each defined target.
45
53
  */
46
54
  handleEvent(event: Event): void;
55
+ /**
56
+ * Execute the effect for all targets.
57
+ */
58
+ private executeEffect;
47
59
  /**
48
60
  * Bind the defined event to the given Action instance root element.
49
61
  */
@@ -6,6 +6,10 @@ class ActionEvent {
6
6
  static modifierSeparator = ".";
7
7
  static targetSeparator = " ";
8
8
  static effectSeparator = "->";
9
+ /**
10
+ * Timer for debouncing event handling.
11
+ */
12
+ debounceTimer;
9
13
  /**
10
14
  * The Action instance.
11
15
  */
@@ -18,6 +22,10 @@ class ActionEvent {
18
22
  * The modifiers to apply to the event.
19
23
  */
20
24
  modifiers;
25
+ /**
26
+ * The debounce delay in milliseconds.
27
+ */
28
+ debounceDelay = 100;
21
29
  /**
22
30
  * Target definition.
23
31
  * Ex: `Target Target(.selector)`.
@@ -37,7 +45,16 @@ class ActionEvent {
37
45
  this.action = action;
38
46
  const [event, ...modifiers] = eventDefinition.split(ActionEvent.modifierSeparator);
39
47
  this.event = event;
40
- this.modifiers = modifiers;
48
+ const processedModifiers = [];
49
+ for (const modifier of modifiers) {
50
+ if (modifier.startsWith("debounce")) {
51
+ processedModifiers.push("debounce");
52
+ this.debounceDelay = parseInt(modifier.replace("debounce", "") || "100");
53
+ } else {
54
+ processedModifiers.push(modifier);
55
+ }
56
+ }
57
+ this.modifiers = processedModifiers;
41
58
  let effect = effectDefinition;
42
59
  let targetDefinition = "";
43
60
  if (effect.includes(ActionEvent.effectSeparator)) {
@@ -94,6 +111,19 @@ class ActionEvent {
94
111
  if (modifiers.includes("stop")) {
95
112
  event.stopPropagation();
96
113
  }
114
+ if (modifiers.includes("debounce")) {
115
+ clearTimeout(this.debounceTimer);
116
+ this.debounceTimer = window.setTimeout(() => {
117
+ this.executeEffect(targets, effect, event);
118
+ }, this.debounceDelay);
119
+ } else {
120
+ this.executeEffect(targets, effect, event);
121
+ }
122
+ }
123
+ /**
124
+ * Execute the effect for all targets.
125
+ */
126
+ executeEffect(targets, effect, event) {
97
127
  for (const target of targets) {
98
128
  try {
99
129
  const [currentTarget] = Object.values(target).flat();
@@ -121,6 +151,7 @@ class ActionEvent {
121
151
  * Unbind the event from the given Action instance root element.
122
152
  */
123
153
  detachEvent() {
154
+ clearTimeout(this.debounceTimer);
124
155
  this.action.$el.removeEventListener(this.event, this);
125
156
  }
126
157
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/ui/Action/ActionEvent.ts"],
4
- "sourcesContent": ["import { getInstances } from '@studiometa/js-toolkit';\nimport type { Base } from '@studiometa/js-toolkit';\nimport { isFunction } from '@studiometa/js-toolkit/utils';\n\n/**\n * Extract component name and an optional additional selector from a string.\n * @type {RegExp}\n */\nconst TARGET_REGEX = /([a-zA-Z]+)(\\((.*)\\))?/;\n\nconst effectCache = new Map<string, Function>();\n\nexport type Modifiers = 'prevent' | 'stop' | 'once' | 'passive' | 'capture';\n\nexport class ActionEvent<T extends Base> {\n static modifierSeparator = '.';\n static targetSeparator = ' ';\n static effectSeparator = '->';\n\n /**\n * The Action instance.\n */\n action: T;\n\n /**\n * The event to listen to.\n */\n event: string;\n\n /**\n * The modifiers to apply to the event.\n */\n modifiers: Modifiers[];\n\n /**\n * Target definition.\n * Ex: `Target Target(.selector)`.\n */\n targetDefinition: string;\n\n /**\n * The content of the effect callback function.\n */\n effectDefinition: string;\n\n /**\n * Class constructor.\n * @param {T} action The parent Action instance.\n * @param {string} eventDefinition The event with its modifiers: `click.prevent.stop`\n * @param {string} effectDefinition The target and effect definition: `Target(.selector)->target.$destroy()`\n */\n constructor(action: T, eventDefinition: string, effectDefinition: string) {\n this.action = action;\n const [event, ...modifiers] = eventDefinition.split(ActionEvent.modifierSeparator);\n this.event = event;\n this.modifiers = modifiers as Modifiers[];\n\n let effect = effectDefinition;\n let targetDefinition = '';\n\n if (effect.includes(ActionEvent.effectSeparator)) {\n [targetDefinition, effect] = effect.split(ActionEvent.effectSeparator);\n }\n\n this.targetDefinition = targetDefinition.trim();\n this.effectDefinition = effect.trim();\n }\n\n /**\n * Get the generated function for the defined effect.\n */\n get effect() {\n const { effectDefinition } = this;\n\n if (!effectCache.has(effectDefinition)) {\n effectCache.set(\n effectDefinition,\n new Function('ctx', 'event', 'target', 'action', 'self', `return ${effectDefinition}`),\n );\n }\n\n return effectCache.get(effectDefinition) as Function;\n }\n\n /**\n * Get the targets object for the defined targets string.\n */\n get targets() {\n const { targetDefinition } = this;\n\n if (!targetDefinition) {\n return [{ Action: this.action }];\n }\n\n // Extract component's names and selectors.\n const parts = targetDefinition.split(ActionEvent.targetSeparator).map((part) => {\n const [, name, , selector] = part.match(TARGET_REGEX) ?? [];\n return [name, selector];\n });\n\n const targets = [] as Array<Record<string, Base>>;\n\n for (const instance of getInstances()) {\n const { name } = instance.__config;\n\n for (const part of parts) {\n const shouldPush =\n part[0] === name && (!part[1] || (part[1] && instance.$el.matches(part[1])));\n if (shouldPush) {\n targets.push({ [instance.__config.name]: instance });\n }\n }\n }\n\n return targets;\n }\n\n /**\n * Handle the defined event and trigger the effect for each defined target.\n */\n handleEvent(event: Event) {\n const { targets, effect, modifiers } = this;\n\n if (modifiers.includes('prevent')) {\n event.preventDefault();\n }\n\n if (modifiers.includes('stop')) {\n event.stopPropagation();\n }\n\n for (const target of targets) {\n try {\n const [currentTarget] = Object.values(target).flat();\n const value = effect(target, event, currentTarget, this.action, this.action);\n if (isFunction(value)) {\n value(target, event, currentTarget, this.action, this.action);\n }\n } catch (err) {\n this.action.$warn(err);\n }\n }\n }\n\n /**\n * Bind the defined event to the given Action instance root element.\n */\n attachEvent() {\n const { event, modifiers } = this;\n this.action.$el.addEventListener(event, this, {\n capture: modifiers.includes('capture'),\n once: modifiers.includes('once'),\n passive: modifiers.includes('passive'),\n });\n }\n\n /**\n * Unbind the event from the given Action instance root element.\n */\n detachEvent() {\n this.action.$el.removeEventListener(this.event, this);\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { getInstances } from '@studiometa/js-toolkit';\nimport type { Base } from '@studiometa/js-toolkit';\nimport { isFunction } from '@studiometa/js-toolkit/utils';\n\n/**\n * Extract component name and an optional additional selector from a string.\n * @type {RegExp}\n */\nconst TARGET_REGEX = /([a-zA-Z]+)(\\((.*)\\))?/;\n\nconst effectCache = new Map<string, Function>();\n\nexport type Modifiers = 'prevent' | 'stop' | 'once' | 'passive' | 'capture' | 'debounce';\n\nexport class ActionEvent<T extends Base> {\n static modifierSeparator = '.';\n static targetSeparator = ' ';\n static effectSeparator = '->';\n\n /**\n * Timer for debouncing event handling.\n */\n private debounceTimer?: number;\n\n /**\n * The Action instance.\n */\n action: T;\n\n /**\n * The event to listen to.\n */\n event: string;\n\n /**\n * The modifiers to apply to the event.\n */\n modifiers: Modifiers[];\n\n /**\n * The debounce delay in milliseconds.\n */\n debounceDelay: number = 100;\n\n /**\n * Target definition.\n * Ex: `Target Target(.selector)`.\n */\n targetDefinition: string;\n\n /**\n * The content of the effect callback function.\n */\n effectDefinition: string;\n\n /**\n * Class constructor.\n * @param {T} action The parent Action instance.\n * @param {string} eventDefinition The event with its modifiers: `click.prevent.stop`\n * @param {string} effectDefinition The target and effect definition: `Target(.selector)->target.$destroy()`\n */\n constructor(action: T, eventDefinition: string, effectDefinition: string) {\n this.action = action;\n const [event, ...modifiers] = eventDefinition.split(ActionEvent.modifierSeparator);\n this.event = event;\n\n // Process modifiers and extract debounce delay if present\n const processedModifiers: Modifiers[] = [];\n for (const modifier of modifiers) {\n if (modifier.startsWith('debounce')) {\n processedModifiers.push('debounce');\n this.debounceDelay = parseInt(modifier.replace('debounce', '') || '100');\n } else {\n processedModifiers.push(modifier as Modifiers);\n }\n }\n\n this.modifiers = processedModifiers;\n\n let effect = effectDefinition;\n let targetDefinition = '';\n\n if (effect.includes(ActionEvent.effectSeparator)) {\n [targetDefinition, effect] = effect.split(ActionEvent.effectSeparator);\n }\n\n this.targetDefinition = targetDefinition.trim();\n this.effectDefinition = effect.trim();\n }\n\n /**\n * Get the generated function for the defined effect.\n */\n get effect() {\n const { effectDefinition } = this;\n\n if (!effectCache.has(effectDefinition)) {\n effectCache.set(\n effectDefinition,\n new Function('ctx', 'event', 'target', 'action', 'self', `return ${effectDefinition}`),\n );\n }\n\n return effectCache.get(effectDefinition) as Function;\n }\n\n /**\n * Get the targets object for the defined targets string.\n */\n get targets() {\n const { targetDefinition } = this;\n\n if (!targetDefinition) {\n return [{ Action: this.action }];\n }\n\n // Extract component's names and selectors.\n const parts = targetDefinition.split(ActionEvent.targetSeparator).map((part) => {\n const [, name, , selector] = part.match(TARGET_REGEX) ?? [];\n return [name, selector];\n });\n\n const targets = [] as Array<Record<string, Base>>;\n\n for (const instance of getInstances()) {\n const { name } = instance.__config;\n\n for (const part of parts) {\n const shouldPush =\n part[0] === name && (!part[1] || (part[1] && instance.$el.matches(part[1])));\n if (shouldPush) {\n targets.push({ [instance.__config.name]: instance });\n }\n }\n }\n\n return targets;\n }\n\n /**\n * Handle the defined event and trigger the effect for each defined target.\n */\n handleEvent(event: Event) {\n const { targets, effect, modifiers } = this;\n\n if (modifiers.includes('prevent')) {\n event.preventDefault();\n }\n\n if (modifiers.includes('stop')) {\n event.stopPropagation();\n }\n\n if (modifiers.includes('debounce')) {\n clearTimeout(this.debounceTimer);\n this.debounceTimer = window.setTimeout(() => {\n this.executeEffect(targets, effect, event);\n }, this.debounceDelay);\n } else {\n this.executeEffect(targets, effect, event);\n }\n }\n\n /**\n * Execute the effect for all targets.\n */\n private executeEffect(targets: Array<Record<string, Base>>, effect: Function, event: Event) {\n for (const target of targets) {\n try {\n const [currentTarget] = Object.values(target).flat();\n const value = effect(target, event, currentTarget, this.action, this.action);\n if (isFunction(value)) {\n value(target, event, currentTarget, this.action, this.action);\n }\n } catch (err) {\n this.action.$warn(err);\n }\n }\n }\n\n /**\n * Bind the defined event to the given Action instance root element.\n */\n attachEvent() {\n const { event, modifiers } = this;\n this.action.$el.addEventListener(event, this, {\n capture: modifiers.includes('capture'),\n once: modifiers.includes('once'),\n passive: modifiers.includes('passive'),\n });\n }\n\n /**\n * Unbind the event from the given Action instance root element.\n */\n detachEvent() {\n clearTimeout(this.debounceTimer);\n this.action.$el.removeEventListener(this.event, this);\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,7 +2,7 @@ import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';
2
2
  import { Transition } from '../Transition/index.js';
3
3
  export interface FrameTargetProps extends BaseProps {
4
4
  $options: {
5
- mode: 'replace' | 'prepend' | 'append';
5
+ mode: 'replace' | 'prepend' | 'append' | 'morph';
6
6
  };
7
7
  }
8
8
  /**
@@ -20,6 +20,7 @@ export declare class FrameTarget<T extends BaseProps = BaseProps> extends Transi
20
20
  readonly APPEND: "append";
21
21
  readonly PREPEND: "prepend";
22
22
  readonly REPLACE: "replace";
23
+ readonly MORPH: "morph";
23
24
  };
24
25
  /**
25
26
  * Get uniq ID.
@@ -20,7 +20,8 @@ class FrameTarget extends Transition {
20
20
  modes = {
21
21
  APPEND: "append",
22
22
  PREPEND: "prepend",
23
- REPLACE: "replace"
23
+ REPLACE: "replace",
24
+ MORPH: "morph"
24
25
  };
25
26
  /**
26
27
  * Get uniq ID.
@@ -36,17 +37,22 @@ class FrameTarget extends Transition {
36
37
  return;
37
38
  }
38
39
  const { mode } = this.$options;
39
- if (mode === this.modes.APPEND || mode === this.modes.PREPEND) {
40
- const leaveTargets = Array.from(this.$el.children);
40
+ const { $el, modes } = this;
41
+ if (mode === modes.APPEND || mode === modes.PREPEND) {
42
+ const leaveTargets = Array.from($el.children);
41
43
  const enterTargets = Array.from(content.children);
42
- this.$el[mode](...Array.from(content.childNodes));
44
+ $el[mode](...Array.from(content.childNodes));
43
45
  await Promise.all([
44
46
  this.leave(leaveTargets),
45
47
  this.enter(enterTargets)
46
48
  ]);
47
49
  } else {
48
50
  await this.leave();
49
- morphdom(this.$el, content);
51
+ if (mode === modes.MORPH) {
52
+ morphdom($el, content);
53
+ } else {
54
+ $el.replaceChildren(...Array.from(content.childNodes));
55
+ }
50
56
  await this.enter();
51
57
  }
52
58
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/ui/Frame/FrameTarget.ts"],
4
- "sourcesContent": ["import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport { Transition } from '../Transition/index.js';\nimport morphdom from 'morphdom';\n\nexport interface FrameTargetProps extends BaseProps {\n $options: {\n mode: 'replace' | 'prepend' | 'append';\n };\n}\n\n/**\n * FrameTarget class.\n */\nexport class FrameTarget<T extends BaseProps = BaseProps> extends Transition<T & FrameTargetProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'FrameTarget',\n options: {\n mode: {\n type: String,\n default: 'replace', // or 'prepend' or 'append'\n },\n },\n };\n\n /**\n * Different mode of content insertion.\n */\n modes = {\n APPEND: 'append',\n PREPEND: 'prepend',\n REPLACE: 'replace',\n } as const;\n\n /**\n * Get uniq ID.\n */\n get id(): string {\n return this.$el.id;\n }\n\n /**\n * Update the content from the new target.\n */\n async updateContent(content: Element = null) {\n if (!content) {\n return;\n }\n\n const { mode } = this.$options;\n\n // In append or prepend mode, the leave transition can be used to\n // move the exisiting children of the root element, with the leave\n // transition being applied in parallel of the enter transition.\n if (mode === this.modes.APPEND || mode === this.modes.PREPEND) {\n const leaveTargets = Array.from(this.$el.children) as HTMLElement[];\n const enterTargets = Array.from(content.children) as HTMLElement[];\n\n this.$el[mode](...Array.from(content.childNodes));\n\n await Promise.all([\n this.leave(leaveTargets),\n this.enter(enterTargets),\n ]);\n } else {\n await this.leave();\n morphdom(this.$el, content);\n await this.enter();\n }\n }\n}\n"],
5
- "mappings": "AACA,SAAS,kBAAkB;AAC3B,OAAO,cAAc;AAWd,MAAM,oBAAqD,WAAiC;AAAA;AAAA;AAAA;AAAA,EAIjG,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,SAAS;AAAA;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,EACX;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAa;AACf,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,UAAmB,MAAM;AAC3C,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,UAAM,EAAE,KAAK,IAAI,KAAK;AAKtB,QAAI,SAAS,KAAK,MAAM,UAAU,SAAS,KAAK,MAAM,SAAS;AAC7D,YAAM,eAAe,MAAM,KAAK,KAAK,IAAI,QAAQ;AACjD,YAAM,eAAe,MAAM,KAAK,QAAQ,QAAQ;AAEhD,WAAK,IAAI,IAAI,EAAE,GAAG,MAAM,KAAK,QAAQ,UAAU,CAAC;AAEhD,YAAM,QAAQ,IAAI;AAAA,QAChB,KAAK,MAAM,YAAY;AAAA,QACvB,KAAK,MAAM,YAAY;AAAA,MACzB,CAAC;AAAA,IACH,OAAO;AACL,YAAM,KAAK,MAAM;AACjB,eAAS,KAAK,KAAK,OAAO;AAC1B,YAAM,KAAK,MAAM;AAAA,IACnB;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport { Transition } from '../Transition/index.js';\nimport morphdom from 'morphdom';\n\nexport interface FrameTargetProps extends BaseProps {\n $options: {\n mode: 'replace' | 'prepend' | 'append' | 'morph';\n };\n}\n\n/**\n * FrameTarget class.\n */\nexport class FrameTarget<T extends BaseProps = BaseProps> extends Transition<T & FrameTargetProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'FrameTarget',\n options: {\n mode: {\n type: String,\n default: 'replace', // or 'prepend' or 'append'\n },\n },\n };\n\n /**\n * Different mode of content insertion.\n */\n modes = {\n APPEND: 'append',\n PREPEND: 'prepend',\n REPLACE: 'replace',\n MORPH: 'morph',\n } as const;\n\n /**\n * Get uniq ID.\n */\n get id(): string {\n return this.$el.id;\n }\n\n /**\n * Update the content from the new target.\n */\n async updateContent(content: Element = null) {\n if (!content) {\n return;\n }\n\n const { mode } = this.$options;\n const { $el, modes } = this;\n\n // In append or prepend mode, the leave transition can be used to\n // move the exisiting children of the root element, with the leave\n // transition being applied in parallel of the enter transition.\n if (mode === modes.APPEND || mode === modes.PREPEND) {\n const leaveTargets = Array.from($el.children) as HTMLElement[];\n const enterTargets = Array.from(content.children) as HTMLElement[];\n\n $el[mode](...Array.from(content.childNodes));\n\n await Promise.all([\n this.leave(leaveTargets),\n this.enter(enterTargets),\n ]);\n } else {\n await this.leave();\n if (mode === modes.MORPH) {\n morphdom($el, content);\n } else {\n $el.replaceChildren(...Array.from(content.childNodes));\n }\n await this.enter();\n }\n }\n}\n"],
5
+ "mappings": "AACA,SAAS,kBAAkB;AAC3B,OAAO,cAAc;AAWd,MAAM,oBAAqD,WAAiC;AAAA;AAAA;AAAA;AAAA,EAIjG,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,SAAS;AAAA,MACP,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,SAAS;AAAA;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ;AAAA,IACN,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,SAAS;AAAA,IACT,OAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,KAAa;AACf,WAAO,KAAK,IAAI;AAAA,EAClB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,cAAc,UAAmB,MAAM;AAC3C,QAAI,CAAC,SAAS;AACZ;AAAA,IACF;AAEA,UAAM,EAAE,KAAK,IAAI,KAAK;AACtB,UAAM,EAAE,KAAK,MAAM,IAAI;AAKvB,QAAI,SAAS,MAAM,UAAU,SAAS,MAAM,SAAS;AACnD,YAAM,eAAe,MAAM,KAAK,IAAI,QAAQ;AAC5C,YAAM,eAAe,MAAM,KAAK,QAAQ,QAAQ;AAEhD,UAAI,IAAI,EAAE,GAAG,MAAM,KAAK,QAAQ,UAAU,CAAC;AAE3C,YAAM,QAAQ,IAAI;AAAA,QAChB,KAAK,MAAM,YAAY;AAAA,QACvB,KAAK,MAAM,YAAY;AAAA,MACzB,CAAC;AAAA,IACH,OAAO;AACL,YAAM,KAAK,MAAM;AACjB,UAAI,SAAS,MAAM,OAAO;AACxB,iBAAS,KAAK,OAAO;AAAA,MACvB,OAAO;AACL,YAAI,gBAAgB,GAAG,MAAM,KAAK,QAAQ,UAAU,CAAC;AAAA,MACvD;AACA,YAAM,KAAK,MAAM;AAAA,IACnB;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studiometa/ui",
3
- "version": "1.0.0-rc.7",
3
+ "version": "1.0.1",
4
4
  "description": "A set of opiniated, unstyled and accessible components",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -33,9 +33,9 @@
33
33
  "morphdom": "^2.7.5"
34
34
  },
35
35
  "devDependencies": {
36
- "@studiometa/js-toolkit": "3.0.4"
36
+ "@studiometa/js-toolkit": "3.0.5"
37
37
  },
38
38
  "peerDependencies": {
39
- "@studiometa/js-toolkit": "^3.0.4"
39
+ "@studiometa/js-toolkit": "^3.0.5"
40
40
  }
41
41
  }