mirror of
https://github.com/penpot/penpot.git
synced 2025-01-04 13:50:12 -05:00
Merge remote-tracking branch 'origin/develop' into develop
This commit is contained in:
commit
1c76587d70
19 changed files with 1291 additions and 317 deletions
|
@ -2,7 +2,7 @@
|
|||
const config = {
|
||||
stories: ["../src/**/*.mdx", "../src/**/*.stories.@(js|jsx|mjs|ts|tsx)"],
|
||||
staticDirs: ["../resources/public"],
|
||||
addons: ["@storybook/addon-essentials", "@storybook/addon-themes"],
|
||||
addons: ["@storybook/addon-essentials", "@storybook/addon-themes", "@storybook/addon-interactions"],
|
||||
core: {
|
||||
builder: "@storybook/builder-vite",
|
||||
options: {
|
||||
|
|
|
@ -48,11 +48,13 @@
|
|||
},
|
||||
"devDependencies": {
|
||||
"@playwright/test": "1.48.1",
|
||||
"@storybook/addon-essentials": "^8.3.6",
|
||||
"@storybook/addon-themes": "^8.3.6",
|
||||
"@storybook/blocks": "^8.3.6",
|
||||
"@storybook/react": "^8.3.6",
|
||||
"@storybook/react-vite": "^8.3.6",
|
||||
"@storybook/addon-essentials": "^8.4.6",
|
||||
"@storybook/addon-interactions": "^8.4.6",
|
||||
"@storybook/addon-themes": "^8.4.6",
|
||||
"@storybook/blocks": "^8.4.6",
|
||||
"@storybook/react": "^8.4.6",
|
||||
"@storybook/react-vite": "^8.4.6",
|
||||
"@storybook/test": "^8.4.6",
|
||||
"@types/node": "^22.7.7",
|
||||
"autoprefixer": "^10.4.20",
|
||||
"concurrently": "^9.0.1",
|
||||
|
@ -86,7 +88,7 @@
|
|||
"sass": "^1.80.3",
|
||||
"sass-embedded": "^1.80.3",
|
||||
"shadow-cljs": "2.28.18",
|
||||
"storybook": "^8.3.6",
|
||||
"storybook": "^8.4.6",
|
||||
"svg-sprite": "^2.0.4",
|
||||
"typescript": "^5.6.3",
|
||||
"vite": "^5.4.9",
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
[app.config :as cf]
|
||||
[app.main.ui.ds.buttons.button :refer [button*]]
|
||||
[app.main.ui.ds.buttons.icon-button :refer [icon-button*]]
|
||||
[app.main.ui.ds.controls.combobox :refer [combobox*]]
|
||||
[app.main.ui.ds.controls.input :refer [input*]]
|
||||
[app.main.ui.ds.controls.select :refer [select*]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list]]
|
||||
|
@ -38,6 +39,7 @@
|
|||
:Loader loader*
|
||||
:RawSvg raw-svg*
|
||||
:Select select*
|
||||
:Combobox combobox*
|
||||
:Text text*
|
||||
:TabSwitcher tab-switcher*
|
||||
:Toast toast*
|
||||
|
|
252
frontend/src/app/main/ui/ds/controls/combobox.cljs
Normal file
252
frontend/src/app/main/ui/ds/controls/combobox.cljs
Normal file
|
@ -0,0 +1,252 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.ds.controls.combobox
|
||||
(:require-macros
|
||||
[app.common.data.macros :as dm]
|
||||
[app.main.style :as stl])
|
||||
(:require
|
||||
[app.main.ui.ds.controls.shared.options-dropdown :refer [options-dropdown*]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list] :as i]
|
||||
[app.util.array :as array]
|
||||
[app.util.dom :as dom]
|
||||
[app.util.keyboard :as kbd]
|
||||
[app.util.object :as obj]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(def listbox-id-index (atom 0))
|
||||
|
||||
(defn- get-option
|
||||
[options id]
|
||||
(array/find #(= id (obj/get % "id")) options))
|
||||
|
||||
(defn- handle-focus-change
|
||||
[options focused* new-index options-nodes-refs]
|
||||
(let [option (aget options new-index)
|
||||
id (obj/get option "id")
|
||||
nodes (mf/ref-val options-nodes-refs)
|
||||
node (obj/get nodes id)]
|
||||
(reset! focused* id)
|
||||
(dom/scroll-into-view-if-needed! node)))
|
||||
|
||||
(defn- handle-selection
|
||||
[focused* selected* open*]
|
||||
(when-let [focused (deref focused*)]
|
||||
(reset! selected* focused))
|
||||
(reset! open* false)
|
||||
(reset! focused* nil))
|
||||
|
||||
(def ^:private schema:combobox-option
|
||||
[:and
|
||||
[:map {:title "option"}
|
||||
[:id :string]
|
||||
[:icon {:optional true}
|
||||
[:and :string [:fn #(contains? icon-list %)]]]
|
||||
[:label {:optional true} :string]
|
||||
[:aria-label {:optional true} :string]]
|
||||
[:fn {:error/message "invalid data: missing required props"}
|
||||
(fn [option]
|
||||
(or (and (contains? option :icon)
|
||||
(or (contains? option :label)
|
||||
(contains? option :aria-label)))
|
||||
(contains? option :label)))]])
|
||||
|
||||
(def ^:private schema:combobox
|
||||
[:map
|
||||
[:options [:vector {:min 1} schema:combobox-option]]
|
||||
[:class {:optional true} :string]
|
||||
[:disabled {:optional true} :boolean]
|
||||
[:default-selected {:optional true} :string]
|
||||
[:on-change {:optional true} fn?]])
|
||||
|
||||
(mf/defc combobox*
|
||||
{::mf/props :obj
|
||||
::mf/schema schema:combobox}
|
||||
[{:keys [options class disabled default-selected on-change] :rest props}]
|
||||
(let [open* (mf/use-state false)
|
||||
open (deref open*)
|
||||
|
||||
selected* (mf/use-state default-selected)
|
||||
selected (deref selected*)
|
||||
|
||||
focused* (mf/use-state nil)
|
||||
focused (deref focused*)
|
||||
|
||||
has-focus* (mf/use-state false)
|
||||
has-focus (deref has-focus*)
|
||||
|
||||
dropdown-options
|
||||
(mf/use-memo
|
||||
(mf/deps options selected)
|
||||
(fn []
|
||||
(->> options
|
||||
(array/filter (fn [option]
|
||||
(let [lower-option (.toLowerCase (obj/get option "id"))
|
||||
lower-filter (.toLowerCase selected)]
|
||||
(.includes lower-option lower-filter)))))))
|
||||
|
||||
on-click
|
||||
(mf/use-fn
|
||||
(mf/deps disabled)
|
||||
(fn [event]
|
||||
(dom/stop-propagation event)
|
||||
(when-not disabled
|
||||
(reset! has-focus* true)
|
||||
(if (= "INPUT" (.-tagName (.-target event)))
|
||||
(reset! open* true)
|
||||
(swap! open* not)))))
|
||||
|
||||
on-option-click
|
||||
(mf/use-fn
|
||||
(mf/deps on-change)
|
||||
(fn [event]
|
||||
(let [node (dom/get-current-target event)
|
||||
id (dom/get-data node "id")]
|
||||
(reset! selected* id)
|
||||
(reset! focused* nil)
|
||||
(reset! open* false)
|
||||
(when (fn? on-change)
|
||||
(on-change id)))))
|
||||
|
||||
options-nodes-refs (mf/use-ref nil)
|
||||
options-ref (mf/use-ref nil)
|
||||
listbox-id-ref (mf/use-ref (dm/str "listbox-" (swap! listbox-id-index inc)))
|
||||
listbox-id (mf/ref-val listbox-id-ref)
|
||||
combobox-ref (mf/use-ref nil)
|
||||
|
||||
set-ref
|
||||
(mf/use-fn
|
||||
(fn [node id]
|
||||
(let [refs (or (mf/ref-val options-nodes-refs) #js {})
|
||||
refs (if node
|
||||
(obj/set! refs id node)
|
||||
(obj/unset! refs id))]
|
||||
(mf/set-ref-val! options-nodes-refs refs))))
|
||||
|
||||
on-blur
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(let [target (.-relatedTarget event)
|
||||
outside? (not (.contains (mf/ref-val combobox-ref) target))]
|
||||
(when outside?
|
||||
(reset! focused* nil)
|
||||
(reset! open* false)
|
||||
(reset! has-focus* false)))))
|
||||
|
||||
on-key-down
|
||||
(mf/use-fn
|
||||
(mf/deps open focused disabled dropdown-options)
|
||||
(fn [event]
|
||||
(when-not disabled
|
||||
(let [options dropdown-options
|
||||
focused (deref focused*)
|
||||
len (alength options)
|
||||
index (array/find-index #(= (deref focused*) (obj/get % "id")) options)]
|
||||
(dom/stop-propagation event)
|
||||
|
||||
(when (< len 0)
|
||||
(reset! index len))
|
||||
|
||||
(cond
|
||||
(and (not open) (kbd/down-arrow? event))
|
||||
(reset! open* true)
|
||||
|
||||
open
|
||||
(cond
|
||||
(kbd/home? event)
|
||||
(handle-focus-change options focused* 0 options-nodes-refs)
|
||||
|
||||
(kbd/up-arrow? event)
|
||||
(let [new-index (if (= index -1)
|
||||
(dec len)
|
||||
(mod (- index 1) len))]
|
||||
(handle-focus-change options focused* new-index options-nodes-refs))
|
||||
|
||||
|
||||
(kbd/down-arrow? event)
|
||||
(let [new-index (if (= index -1)
|
||||
0
|
||||
(mod (+ index 1) len))]
|
||||
(handle-focus-change options focused* new-index options-nodes-refs))
|
||||
|
||||
(or (kbd/space? event) (kbd/enter? event))
|
||||
(when (deref open*)
|
||||
(dom/prevent-default event)
|
||||
(handle-selection focused* selected* open*)
|
||||
(when (fn? on-change)
|
||||
(on-change focused)))
|
||||
|
||||
(kbd/esc? event)
|
||||
(do (reset! open* false)
|
||||
(reset! focused* nil))))))))
|
||||
|
||||
on-input-change
|
||||
(mf/use-fn
|
||||
(fn [event]
|
||||
(let [value (.-value (.-currentTarget event))]
|
||||
(reset! selected* value)
|
||||
(reset! focused* nil)
|
||||
(when (fn? on-change)
|
||||
(on-change value)))))
|
||||
on-focus
|
||||
(mf/use-fn
|
||||
(fn [_] (reset! has-focus* true)))
|
||||
|
||||
class (dm/str class " " (stl/css :combobox))
|
||||
|
||||
selected-option (get-option options selected)
|
||||
icon (obj/get selected-option "icon")]
|
||||
|
||||
(mf/with-effect [options]
|
||||
(mf/set-ref-val! options-ref options))
|
||||
|
||||
[:div {:ref combobox-ref
|
||||
:class (stl/css-case
|
||||
:combobox-wrapper true
|
||||
:focused has-focus)}
|
||||
|
||||
[:div {:class class
|
||||
:on-click on-click
|
||||
:on-focus on-focus
|
||||
:on-blur on-blur}
|
||||
[:span {:class (stl/css-case :combobox-header true
|
||||
:header-icon (some? icon))}
|
||||
(when icon
|
||||
[:> icon* {:id icon
|
||||
:size "s"
|
||||
:aria-hidden true}])
|
||||
[:input {:type "text"
|
||||
:role "combobox"
|
||||
:aria-autocomplete "both"
|
||||
:aria-expanded open
|
||||
:aria-controls listbox-id
|
||||
:aria-activedescendant focused
|
||||
:class (stl/css :input)
|
||||
:data-testid "combobox-input"
|
||||
:disabled disabled
|
||||
:value selected
|
||||
:on-change on-input-change
|
||||
:on-key-down on-key-down}]]
|
||||
|
||||
[:> :button {:tab-index "-1"
|
||||
:aria-expanded open
|
||||
:aria-controls listbox-id
|
||||
:class (stl/css :button-toggle-list)
|
||||
:on-click on-click}
|
||||
[:> icon* {:id i/arrow
|
||||
:class (stl/css :arrow)
|
||||
:size "s"
|
||||
:aria-hidden true
|
||||
:data-testid "combobox-open-button"}]]]
|
||||
|
||||
(when (and open (seq dropdown-options))
|
||||
[:> options-dropdown* {:on-click on-option-click
|
||||
:options dropdown-options
|
||||
:selected selected
|
||||
:focused focused
|
||||
:set-ref set-ref
|
||||
:id listbox-id
|
||||
:data-testid "combobox-options"}])]))
|
62
frontend/src/app/main/ui/ds/controls/combobox.mdx
Normal file
62
frontend/src/app/main/ui/ds/controls/combobox.mdx
Normal file
|
@ -0,0 +1,62 @@
|
|||
import { Canvas, Meta } from "@storybook/blocks";
|
||||
import * as ComboboxStories from "./combobox.stories";
|
||||
|
||||
<Meta title="Controls/Combobox" />
|
||||
|
||||
# Combobox
|
||||
|
||||
Combobox lets users choose one option from an options menu or enter a custom value that is not listed in the menu. It combines the functionality of a dropdown menu and an input field, allowing for both selection and free-form input.
|
||||
|
||||
## Variants
|
||||
|
||||
**Text**: We will use this variant when there are enough space and icons don't add any useful context.
|
||||
|
||||
<Canvas of={ComboboxStories.Default} />
|
||||
|
||||
**Icon and text**: We will use this variant when there are enough space and icons add any useful context.
|
||||
|
||||
<Canvas of={ComboboxStories.WithIcons} />
|
||||
|
||||
## Technical notes
|
||||
|
||||
### Icons
|
||||
|
||||
Each option of `combobox*` may accept an `icon`, which must contain an [icon ID](../foundations/assets/icon.mdx).
|
||||
These are available in the `app.main.ds.foundations.assets.icon` namespace.
|
||||
|
||||
```clj
|
||||
(ns app.main.ui.foo
|
||||
(:require
|
||||
[app.main.ui.ds.foundations.assets.icon :as i]))
|
||||
```
|
||||
|
||||
```clj
|
||||
[:> combobox*
|
||||
{:options [{ :label "Code"
|
||||
:id "option-code"
|
||||
:icon i/fill-content }
|
||||
{ :label "Design"
|
||||
:id "option-design"
|
||||
:icon i/pentool }
|
||||
{ :label "Menu"
|
||||
:id "option-menu" }
|
||||
]}]
|
||||
```
|
||||
|
||||
<Canvas of={ComboboxStories.WithIcons} />
|
||||
|
||||
## Usage guidelines (design)
|
||||
|
||||
### Where to Use
|
||||
|
||||
Combobox is used in applications where users need to select from a range of text-based options or enter custom input.
|
||||
|
||||
### When to Use
|
||||
|
||||
Consider using a combobox when you have five or more options to present, and users may benefit from the ability to search or input a custom value that is not in the predefined list.
|
||||
|
||||
### Interaction / Behavior
|
||||
|
||||
- **Opening Options**: When the user clicks on the input area, a dropdown menu of options appears. Users can either scroll through the options, type to filter them, or input a new value directly.
|
||||
- **Selecting an Option**: Once an option is selected or a custom value is entered, the dropdown closes, and the input field displays the chosen value.
|
||||
- **Keyboard Support**: Combobox supports navigation using keyboard input, including arrow keys to navigate the list and Enter to make a selection.
|
87
frontend/src/app/main/ui/ds/controls/combobox.scss
Normal file
87
frontend/src/app/main/ui/ds/controls/combobox.scss
Normal file
|
@ -0,0 +1,87 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@use "../_borders.scss" as *;
|
||||
@use "../_sizes.scss" as *;
|
||||
@use "../typography.scss" as *;
|
||||
|
||||
.combobox-wrapper {
|
||||
--combobox-icon-fg-color: var(--color-foreground-secondary);
|
||||
--combobox-fg-color: var(--color-foreground-primary);
|
||||
--combobox-bg-color: var(--color-background-tertiary);
|
||||
--combobox-outline-color: none;
|
||||
--combobox-border-color: none;
|
||||
|
||||
@include use-typography("body-small");
|
||||
position: relative;
|
||||
display: grid;
|
||||
grid-template-rows: auto;
|
||||
gap: var(--sp-xxs);
|
||||
width: 100%;
|
||||
|
||||
&:hover {
|
||||
--combobox-bg-color: var(--color-background-quaternary);
|
||||
}
|
||||
}
|
||||
|
||||
.combobox {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: var(--sp-xs);
|
||||
height: $sz-32;
|
||||
width: 100%;
|
||||
padding: var(--sp-s);
|
||||
border: none;
|
||||
border-radius: $br-8;
|
||||
outline: $b-1 solid var(--combobox-outline-color);
|
||||
border: $b-1 solid var(--combobox-border-color);
|
||||
background: var(--combobox-bg-color);
|
||||
color: var(--combobox-fg-color);
|
||||
appearance: none;
|
||||
|
||||
&:disabled {
|
||||
--combobox-bg-color: var(--color-background-primary);
|
||||
--combobox-border-color: var(--color-background-quaternary);
|
||||
--combobox-fg-color: var(--color-foreground-secondary);
|
||||
}
|
||||
}
|
||||
|
||||
.focused {
|
||||
--combobox-outline-color: var(--color-accent-primary);
|
||||
}
|
||||
|
||||
.arrow {
|
||||
color: var(--combobox-icon-fg-color);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
|
||||
.combobox-header {
|
||||
display: grid;
|
||||
justify-items: start;
|
||||
gap: var(--sp-xs);
|
||||
}
|
||||
|
||||
.input {
|
||||
all: unset;
|
||||
|
||||
@include use-typography("body-small");
|
||||
background-color: transparent;
|
||||
overflow: hidden;
|
||||
text-align: left;
|
||||
inline-size: 100%;
|
||||
padding-inline-start: var(--sp-xxs);
|
||||
color: var(--combobox-fg-color);
|
||||
}
|
||||
|
||||
.header-icon {
|
||||
grid-template-columns: auto 1fr;
|
||||
color: var(--combobox-icon-fg-color);
|
||||
}
|
||||
|
||||
.button-toggle-list {
|
||||
all: unset;
|
||||
display: flex;
|
||||
}
|
216
frontend/src/app/main/ui/ds/controls/combobox.stories.jsx
Normal file
216
frontend/src/app/main/ui/ds/controls/combobox.stories.jsx
Normal file
|
@ -0,0 +1,216 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
import * as React from "react";
|
||||
import Components from "@target/components";
|
||||
|
||||
import { userEvent, within, expect } from "@storybook/test";
|
||||
|
||||
const { Combobox } = Components;
|
||||
|
||||
let lastValue = null;
|
||||
|
||||
export default {
|
||||
title: "Controls/Combobox",
|
||||
component: Combobox,
|
||||
argTypes: {
|
||||
disabled: { control: "boolean" },
|
||||
},
|
||||
args: {
|
||||
disabled: false,
|
||||
options: [
|
||||
{ id: "January", label: "January" },
|
||||
{ id: "February", label: "February" },
|
||||
{ id: "March", label: "March" },
|
||||
{ id: "April", label: "April" },
|
||||
{ id: "May", label: "May" },
|
||||
{ id: "June", label: "June" },
|
||||
{ id: "July", label: "July" },
|
||||
{ id: "August", label: "August" },
|
||||
{ id: "September", label: "September" },
|
||||
{ id: "October", label: "October" },
|
||||
{ id: "November", label: "November" },
|
||||
{ id: "December", label: "December" },
|
||||
],
|
||||
defaultSelected: "February",
|
||||
onChange: (value) => (lastValue = value),
|
||||
},
|
||||
parameters: {
|
||||
controls: {
|
||||
exclude: ["options", "defaultSelected"],
|
||||
},
|
||||
},
|
||||
render: ({ ...args }) => (
|
||||
<div style={{ padding: "5px" }}>
|
||||
<Combobox {...args} />
|
||||
</div>
|
||||
),
|
||||
};
|
||||
|
||||
export const Default = {
|
||||
parameters: {
|
||||
docs: {
|
||||
story: {
|
||||
height: "450px",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const WithIcons = {
|
||||
args: {
|
||||
options: [
|
||||
{ id: "January", label: "January", icon: "fill-content" },
|
||||
{ id: "February", label: "February", icon: "pentool" },
|
||||
{ id: "March", label: "March" },
|
||||
{ id: "April", label: "April" },
|
||||
{ id: "May", label: "May" },
|
||||
{ id: "June", label: "June" },
|
||||
{ id: "July", label: "July" },
|
||||
{ id: "August", label: "August" },
|
||||
{ id: "September", label: "September" },
|
||||
{ id: "October", label: "October" },
|
||||
{ id: "November", label: "November" },
|
||||
{ id: "December", label: "December" },
|
||||
],
|
||||
},
|
||||
parameters: {
|
||||
docs: {
|
||||
story: {
|
||||
height: "450px",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const TestInteractions = {
|
||||
...WithIcons,
|
||||
play: async ({ canvasElement, step }) => {
|
||||
const canvas = within(canvasElement);
|
||||
|
||||
const combobox = await canvas.getByRole("combobox");
|
||||
const button = await canvas.getByTestId("combobox-open-button");
|
||||
const input = await canvas.getByTestId("combobox-input");
|
||||
|
||||
const waitOptionNotPresent = async () => {
|
||||
expect(canvas.queryByTestId("combobox-options")).not.toBeInTheDocument();
|
||||
};
|
||||
|
||||
const waitOptionsPresent = async () => {
|
||||
const options = await canvas.findByTestId("combobox-options");
|
||||
expect(options).toBeVisible();
|
||||
|
||||
return options;
|
||||
};
|
||||
|
||||
await userEvent.clear(input);
|
||||
|
||||
await step("Toggle dropdown on click arrow button", async () => {
|
||||
await userEvent.click(button);
|
||||
|
||||
await waitOptionsPresent();
|
||||
expect(combobox).toHaveAttribute("aria-expanded", "true");
|
||||
|
||||
await userEvent.click(button);
|
||||
await waitOptionNotPresent();
|
||||
expect(combobox).toHaveAttribute("aria-expanded", "false");
|
||||
});
|
||||
|
||||
await step("Aria controls is set correctly", async () => {
|
||||
await userEvent.click(button);
|
||||
|
||||
const ariaControls = combobox.getAttribute("aria-controls");
|
||||
|
||||
const options = await canvas.findByTestId("combobox-options");
|
||||
|
||||
expect(options).toHaveAttribute("id", ariaControls);
|
||||
});
|
||||
|
||||
await step("Navigation keys", async () => {
|
||||
// Arrow down
|
||||
await userEvent.click(input);
|
||||
await waitOptionsPresent();
|
||||
|
||||
await userEvent.keyboard("{ArrowDown}");
|
||||
await userEvent.keyboard("{ArrowDown}");
|
||||
await userEvent.keyboard("{Enter}");
|
||||
|
||||
expect(input).toHaveValue("February");
|
||||
expect(lastValue).toBe("February");
|
||||
await userEvent.clear(input);
|
||||
|
||||
// Arrow up
|
||||
await userEvent.keyboard("{ArrowDown}");
|
||||
await waitOptionsPresent();
|
||||
|
||||
await userEvent.keyboard("{ArrowUp}");
|
||||
await userEvent.keyboard("{ArrowUp}");
|
||||
expect(combobox).toHaveAttribute("aria-activedescendant", "November");
|
||||
await userEvent.keyboard("{Enter}");
|
||||
|
||||
expect(input).toHaveValue("November");
|
||||
expect(lastValue).toBe("November");
|
||||
await userEvent.clear(input);
|
||||
|
||||
// Home
|
||||
await userEvent.keyboard("{ArrowDown}");
|
||||
await waitOptionsPresent();
|
||||
|
||||
await userEvent.keyboard("{ArrowDown}");
|
||||
await userEvent.keyboard("{ArrowDown}");
|
||||
await userEvent.keyboard("{Home}");
|
||||
expect(combobox).toHaveAttribute("aria-activedescendant", "January");
|
||||
await userEvent.keyboard("{Enter}");
|
||||
|
||||
expect(input).toHaveValue("January");
|
||||
expect(lastValue).toBe("January");
|
||||
await userEvent.clear(input);
|
||||
});
|
||||
|
||||
await step("Toggle dropdown with arrow down and ESC", async () => {
|
||||
userEvent.click(input);
|
||||
|
||||
await waitOptionsPresent();
|
||||
|
||||
await userEvent.keyboard("{Escape}");
|
||||
expect(combobox).toHaveAttribute("aria-expanded", "false");
|
||||
await waitOptionNotPresent();
|
||||
|
||||
await userEvent.keyboard("{ArrowDown}");
|
||||
await waitOptionsPresent();
|
||||
expect(combobox).toHaveAttribute("aria-expanded", "true");
|
||||
|
||||
await userEvent.keyboard("{Escape}");
|
||||
await waitOptionNotPresent();
|
||||
expect(combobox).toHaveAttribute("aria-expanded", "false");
|
||||
});
|
||||
|
||||
await step("Filter with 'Ju' and select July", async () => {
|
||||
await userEvent.type(input, "Ju");
|
||||
|
||||
const options = await canvas.findAllByTestId("dropdown-option");
|
||||
expect(options).toHaveLength(2);
|
||||
|
||||
await userEvent.keyboard("{ArrowDown}");
|
||||
await userEvent.keyboard("{ArrowDown}");
|
||||
|
||||
await userEvent.keyboard("{Enter}");
|
||||
|
||||
expect(input).toHaveValue("July");
|
||||
expect(lastValue).toBe("July");
|
||||
});
|
||||
|
||||
await step("Close dropdown when focus out", async () => {
|
||||
await userEvent.click(button);
|
||||
|
||||
await waitOptionsPresent();
|
||||
|
||||
await userEvent.tab();
|
||||
|
||||
await waitOptionNotPresent();
|
||||
});
|
||||
},
|
||||
};
|
|
@ -9,6 +9,7 @@
|
|||
[app.common.data.macros :as dm]
|
||||
[app.main.style :as stl])
|
||||
(:require
|
||||
[app.main.ui.ds.controls.shared.options-dropdown :refer [options-dropdown*]]
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon* icon-list] :as i]
|
||||
[app.util.array :as array]
|
||||
[app.util.dom :as dom]
|
||||
|
@ -16,63 +17,6 @@
|
|||
[app.util.object :as obj]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc option*
|
||||
{::mf/props :obj
|
||||
::mf/private true}
|
||||
[{:keys [id label icon aria-label on-click selected set-ref focused] :rest props}]
|
||||
[:> :li {:value id
|
||||
:class (stl/css-case :option true
|
||||
:option-with-icon (some? icon)
|
||||
:option-current focused)
|
||||
:aria-selected selected
|
||||
|
||||
:ref (fn [node]
|
||||
(set-ref node id))
|
||||
:role "option"
|
||||
:id id
|
||||
:on-click on-click
|
||||
:data-id id}
|
||||
|
||||
(when (some? icon)
|
||||
[:> icon*
|
||||
{:id icon
|
||||
:size "s"
|
||||
:class (stl/css :option-icon)
|
||||
:aria-hidden (when label true)
|
||||
:aria-label (when (not label) aria-label)}])
|
||||
|
||||
[:span {:class (stl/css :option-text)} label]
|
||||
(when selected
|
||||
[:> icon*
|
||||
{:id i/tick
|
||||
:size "s"
|
||||
:class (stl/css :option-check)
|
||||
:aria-hidden (when label true)}])])
|
||||
|
||||
(mf/defc options-dropdown*
|
||||
{::mf/props :obj
|
||||
::mf/private true}
|
||||
[{:keys [set-ref on-click options selected focused] :rest props}]
|
||||
(let [props (mf/spread-props props
|
||||
{:class (stl/css :option-list)
|
||||
:tab-index "-1"
|
||||
:role "listbox"})]
|
||||
[:> "ul" props
|
||||
(for [option ^js options]
|
||||
(let [id (obj/get option "id")
|
||||
label (obj/get option "label")
|
||||
aria-label (obj/get option "aria-label")
|
||||
icon (obj/get option "icon")]
|
||||
[:> option* {:selected (= id selected)
|
||||
:key id
|
||||
:id id
|
||||
:label label
|
||||
:icon icon
|
||||
:aria-label aria-label
|
||||
:set-ref set-ref
|
||||
:focused (= id focused)
|
||||
:on-click on-click}]))]))
|
||||
|
||||
(def ^:private schema:select-option
|
||||
[:and
|
||||
[:map {:title "option"}
|
||||
|
|
|
@ -14,7 +14,6 @@
|
|||
--select-bg-color: var(--color-background-tertiary);
|
||||
--select-outline-color: none;
|
||||
--select-border-color: none;
|
||||
--select-dropdown-border-color: var(--color-background-quaternary);
|
||||
|
||||
&:hover {
|
||||
--select-bg-color: var(--color-background-quaternary);
|
||||
|
@ -81,67 +80,3 @@
|
|||
grid-template-columns: auto 1fr;
|
||||
color: var(--select-icon-fg-color);
|
||||
}
|
||||
|
||||
.option-list {
|
||||
--options-dropdown-bg-color: var(--color-background-tertiary);
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: $sz-36;
|
||||
width: 100%;
|
||||
background-color: var(--options-dropdown-bg-color);
|
||||
border-radius: $br-8;
|
||||
border: $b-1 solid var(--select-dropdown-border-color);
|
||||
padding-block: var(--sp-xs);
|
||||
margin-block-end: 0;
|
||||
max-height: $sz-400;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.option {
|
||||
--select-option-fg-color: var(--color-foreground-primary);
|
||||
--select-option-bg-color: unset;
|
||||
|
||||
&:hover {
|
||||
--select-option-bg-color: var(--color-background-quaternary);
|
||||
}
|
||||
|
||||
&[aria-selected="true"] {
|
||||
--select-option-bg-color: var(--color-background-quaternary);
|
||||
}
|
||||
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-items: start;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: var(--sp-xs);
|
||||
width: 100%;
|
||||
height: $sz-32;
|
||||
padding: var(--sp-s);
|
||||
border-radius: $br-8;
|
||||
outline: $b-1 solid var(--select-outline-color);
|
||||
outline-offset: -1px;
|
||||
background-color: var(--select-option-bg-color);
|
||||
}
|
||||
|
||||
.option-with-icon {
|
||||
grid-template-columns: auto 1fr auto;
|
||||
}
|
||||
|
||||
.option-text {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
padding-inline-start: var(--sp-xxs);
|
||||
}
|
||||
|
||||
.option-icon {
|
||||
color: var(--select-icon-fg-color);
|
||||
}
|
||||
|
||||
.option-current {
|
||||
--select-option-outline-color: var(--color-accent-primary);
|
||||
outline: $b-1 solid var(--select-option-outline-color);
|
||||
}
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
;; This Source Code Form is subject to the terms of the Mozilla Public
|
||||
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
;;
|
||||
;; Copyright (c) KALEIDOS INC
|
||||
|
||||
(ns app.main.ui.ds.controls.shared.options-dropdown
|
||||
(:require-macros
|
||||
[app.main.style :as stl])
|
||||
(:require
|
||||
[app.main.ui.ds.foundations.assets.icon :refer [icon*] :as i]
|
||||
[app.util.object :as obj]
|
||||
[rumext.v2 :as mf]))
|
||||
|
||||
(mf/defc option*
|
||||
{::mf/props :obj
|
||||
::mf/private true}
|
||||
[{:keys [id label icon aria-label on-click selected set-ref focused] :rest props}]
|
||||
[:> :li {:value id
|
||||
:class (stl/css-case :option true
|
||||
:option-with-icon (some? icon)
|
||||
:option-current focused)
|
||||
:aria-selected selected
|
||||
:ref (fn [node]
|
||||
(set-ref node id))
|
||||
:role "option"
|
||||
:id id
|
||||
:on-click on-click
|
||||
:data-id id
|
||||
:data-testid "dropdown-option"}
|
||||
|
||||
(when (some? icon)
|
||||
[:> icon*
|
||||
{:id icon
|
||||
:size "s"
|
||||
:class (stl/css :option-icon)
|
||||
:aria-hidden (when label true)
|
||||
:aria-label (when (not label) aria-label)}])
|
||||
|
||||
[:span {:class (stl/css :option-text)} label]
|
||||
(when selected
|
||||
[:> icon*
|
||||
{:id i/tick
|
||||
:size "s"
|
||||
:class (stl/css :option-check)
|
||||
:aria-hidden (when label true)}])])
|
||||
|
||||
(mf/defc options-dropdown*
|
||||
{::mf/props :obj}
|
||||
[{:keys [set-ref on-click options selected focused] :rest props}]
|
||||
(let [props (mf/spread-props props
|
||||
{:class (stl/css :option-list)
|
||||
:tab-index "-1"
|
||||
:role "listbox"})]
|
||||
[:> "ul" props
|
||||
(for [option ^js options]
|
||||
(let [id (obj/get option "id")
|
||||
label (obj/get option "label")
|
||||
aria-label (obj/get option "aria-label")
|
||||
icon (obj/get option "icon")]
|
||||
[:> option* {:selected (= id selected)
|
||||
:key id
|
||||
:id id
|
||||
:label label
|
||||
:icon icon
|
||||
:aria-label aria-label
|
||||
:set-ref set-ref
|
||||
:focused (= id focused)
|
||||
:on-click on-click}]))]))
|
|
@ -0,0 +1,74 @@
|
|||
// This Source Code Form is subject to the terms of the Mozilla Public
|
||||
// License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
//
|
||||
// Copyright (c) KALEIDOS INC
|
||||
|
||||
@use "../../_borders.scss" as *;
|
||||
@use "../../_sizes.scss" as *;
|
||||
@use "../../typography.scss" as *;
|
||||
|
||||
.option-list {
|
||||
--options-dropdown-icon-fg-color: var(--color-foreground-secondary);
|
||||
--options-dropdown-bg-color: var(--color-background-tertiary);
|
||||
--options-dropdown-outline-color: none;
|
||||
--options-dropdown-border-color: var(--color-background-quaternary);
|
||||
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: $sz-36;
|
||||
width: 100%;
|
||||
background-color: var(--options-dropdown-bg-color);
|
||||
border-radius: $br-8;
|
||||
border: $b-1 solid var(--options-dropdown-dropdown-border-color);
|
||||
padding-block: var(--sp-xs);
|
||||
margin-block-end: 0;
|
||||
max-height: $sz-400;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.option {
|
||||
--options-dropdown-fg-color: var(--color-foreground-primary);
|
||||
--options-dropdown-bg-color: unset;
|
||||
|
||||
display: grid;
|
||||
align-items: center;
|
||||
justify-items: start;
|
||||
grid-template-columns: 1fr auto;
|
||||
gap: var(--sp-xs);
|
||||
width: 100%;
|
||||
height: $sz-32;
|
||||
padding: var(--sp-s);
|
||||
border-radius: $br-8;
|
||||
outline: $b-1 solid var(--options-dropdown-outline-color);
|
||||
outline-offset: -1px;
|
||||
background-color: var(--options-dropdown-bg-color);
|
||||
|
||||
&:hover,
|
||||
&[aria-selected="true"] {
|
||||
--options-dropdown-bg-color: var(--color-background-quaternary);
|
||||
}
|
||||
}
|
||||
|
||||
.option-with-icon {
|
||||
grid-template-columns: auto 1fr auto;
|
||||
}
|
||||
|
||||
.option-text {
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
width: 100%;
|
||||
min-width: 0;
|
||||
padding-inline-start: var(--sp-xxs);
|
||||
}
|
||||
|
||||
.option-icon {
|
||||
color: var(--options-dropdown-icon-fg-color);
|
||||
}
|
||||
|
||||
.option-current {
|
||||
--options-dropdown-outline-color: var(--color-accent-primary);
|
||||
outline: $b-1 solid var(--options-dropdown-outline-color);
|
||||
}
|
|
@ -284,7 +284,8 @@
|
|||
(p/fmap (fn [ready?]
|
||||
(when ready?
|
||||
(reset! canvas-init? true)
|
||||
(wasm.api/assign-canvas canvas)))))
|
||||
(wasm.api/assign-canvas canvas)
|
||||
(wasm.api/set-canvas-background background)))))
|
||||
(fn []
|
||||
(wasm.api/clear-canvas))))
|
||||
|
||||
|
@ -304,6 +305,10 @@
|
|||
(when @canvas-init?
|
||||
(wasm.api/set-view zoom vbox)))
|
||||
|
||||
(mf/with-effect [background]
|
||||
(when @canvas-init?
|
||||
(wasm.api/set-canvas-background background)))
|
||||
|
||||
(hooks/setup-dom-events zoom disable-paste in-viewport? read-only? drawing-tool drawing-path?)
|
||||
(hooks/setup-viewport-size vport viewport-ref)
|
||||
(hooks/setup-cursor cursor alt? mod? space? panning drawing-tool drawing-path? node-editing? z? read-only?)
|
||||
|
|
|
@ -345,6 +345,11 @@
|
|||
(set! (.-width canvas) (* dpr (.-clientWidth ^js canvas)))
|
||||
(set! (.-height canvas) (* dpr (.-clientHeight ^js canvas))))
|
||||
|
||||
(defn set-canvas-background
|
||||
[background]
|
||||
(let [rgba (rgba-from-hex background 1)]
|
||||
(h/call internal-module "_set_canvas_background" rgba)))
|
||||
|
||||
(defonce module
|
||||
(delay
|
||||
(if (exists? js/dynamicImport)
|
||||
|
|
|
@ -5,6 +5,13 @@ __metadata:
|
|||
version: 8
|
||||
cacheKey: 10c0
|
||||
|
||||
"@adobe/css-tools@npm:^4.4.0":
|
||||
version: 4.4.1
|
||||
resolution: "@adobe/css-tools@npm:4.4.1"
|
||||
checksum: 10c0/1a68ad9af490f45fce7b6e50dd2d8ac0c546d74431649c0d42ee4ceb1a9fa057fae0a7ef1e148effa12d84ec00ed71869ebfe0fb1dcdcc80bfcb6048c12abcc0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@ampproject/remapping@npm:^2.2.0":
|
||||
version: 2.3.0
|
||||
resolution: "@ampproject/remapping@npm:2.3.0"
|
||||
|
@ -15,7 +22,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.0":
|
||||
"@babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.25.9, @babel/code-frame@npm:^7.26.0":
|
||||
version: 7.26.2
|
||||
resolution: "@babel/code-frame@npm:7.26.2"
|
||||
dependencies:
|
||||
|
@ -633,21 +640,19 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@joshwooding/vite-plugin-react-docgen-typescript@npm:0.3.0":
|
||||
version: 0.3.0
|
||||
resolution: "@joshwooding/vite-plugin-react-docgen-typescript@npm:0.3.0"
|
||||
"@joshwooding/vite-plugin-react-docgen-typescript@npm:0.4.2":
|
||||
version: 0.4.2
|
||||
resolution: "@joshwooding/vite-plugin-react-docgen-typescript@npm:0.4.2"
|
||||
dependencies:
|
||||
glob: "npm:^7.2.0"
|
||||
glob-promise: "npm:^4.2.0"
|
||||
magic-string: "npm:^0.27.0"
|
||||
react-docgen-typescript: "npm:^2.2.2"
|
||||
peerDependencies:
|
||||
typescript: ">= 4.3.x"
|
||||
vite: ^3.0.0 || ^4.0.0 || ^5.0.0
|
||||
vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0
|
||||
peerDependenciesMeta:
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10c0/31098ad8fcc2440437534599c111d9f2951dd74821e8ba46c521b969bae4c918d830b7bb0484efbad29a51711bb62d3bc623d5a1ed5b1695b5b5594ea9dd4ca0
|
||||
checksum: 10c0/355d13ad92a9da786b561a25250e6c94a8e51d235ced345e54ebfe709abc45ab60c2a8d06599df6ec0441fba01720f189883429943cb62dff9a4c31b59f0939c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -1243,9 +1248,9 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-actions@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/addon-actions@npm:8.4.2"
|
||||
"@storybook/addon-actions@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-actions@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/global": "npm:^5.0.0"
|
||||
"@types/uuid": "npm:^9.0.1"
|
||||
|
@ -1253,143 +1258,158 @@ __metadata:
|
|||
polished: "npm:^4.2.2"
|
||||
uuid: "npm:^9.0.0"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/ac89e6e0517efa2f8d6442f8fc0b1c3912bfc1ad50e03cccd06721d3bb52d11f472126a590c746cd565875d8ac11c63457de94e7c1ff6a3f8151b3c6488802d6
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/80b2feceacb4ebe7f2be06b2fe3f49ded5ee08ca8bd036ff47a65d45d8796d29081ccadd0526984c8022bcfa24348e0ad4ce3f37cee4a60a928bae372bfc8afe
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-backgrounds@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/addon-backgrounds@npm:8.4.2"
|
||||
"@storybook/addon-backgrounds@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-backgrounds@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/global": "npm:^5.0.0"
|
||||
memoizerific: "npm:^1.11.3"
|
||||
ts-dedent: "npm:^2.0.0"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/8fac73fafe7974c1710b0565e0fab56b9a3ee35190a06b63e9ae996c5f5a0d214ec755f7e88de8fb8d7493eb022ad820952dffbfc417f2949c07750faea18e46
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/2125d6905bf44194adf79e92698753d5e4ff75fac1ffbba1fc95ae705ba9ac8dc6ca9249c9a862aa05ea207d916d23142faefa759bb9ce21c6e16f0e329d28d2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-controls@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/addon-controls@npm:8.4.2"
|
||||
"@storybook/addon-controls@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-controls@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/global": "npm:^5.0.0"
|
||||
dequal: "npm:^2.0.2"
|
||||
ts-dedent: "npm:^2.0.0"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/8de00a60c34de7972efc3c882912c1b135d4867045783742515741380750a58f4ce0e98139328804adcf1c2926110ca88e2df1135c3b1b03a05b20c97494ef7a
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/f5f0ab2de8de80c8c3726de81802042cc29a6f2ec50de3b8bd463286c9056e87800e4ea9b350c6a41ce4c4175a11cb7d3d490da5cfc20bbf2a2e3549f77a82a7
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-docs@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/addon-docs@npm:8.4.2"
|
||||
"@storybook/addon-docs@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-docs@npm:8.4.6"
|
||||
dependencies:
|
||||
"@mdx-js/react": "npm:^3.0.0"
|
||||
"@storybook/blocks": "npm:8.4.2"
|
||||
"@storybook/csf-plugin": "npm:8.4.2"
|
||||
"@storybook/react-dom-shim": "npm:8.4.2"
|
||||
"@storybook/blocks": "npm:8.4.6"
|
||||
"@storybook/csf-plugin": "npm:8.4.6"
|
||||
"@storybook/react-dom-shim": "npm:8.4.6"
|
||||
react: "npm:^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
react-dom: "npm:^16.8.0 || ^17.0.0 || ^18.0.0"
|
||||
ts-dedent: "npm:^2.0.0"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/ba8046898006b7e0c088ee26e378eff7e9aa315eb0c7ddf6b6d15ad6eea0d544d39674868b2b5ef5c89e64e1dee5501ceceaf2a3854636e88b99f5eaafe4b239
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/ae53bf71048fe7476862ae733f0f765a22d0d1da32457f7ca7e3bdd23bb1cd452c56bc4e1f586cf978599c3f5acb835caeb569ff394eaec09d3259382f4954be
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-essentials@npm:^8.3.6":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/addon-essentials@npm:8.4.2"
|
||||
"@storybook/addon-essentials@npm:^8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-essentials@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/addon-actions": "npm:8.4.2"
|
||||
"@storybook/addon-backgrounds": "npm:8.4.2"
|
||||
"@storybook/addon-controls": "npm:8.4.2"
|
||||
"@storybook/addon-docs": "npm:8.4.2"
|
||||
"@storybook/addon-highlight": "npm:8.4.2"
|
||||
"@storybook/addon-measure": "npm:8.4.2"
|
||||
"@storybook/addon-outline": "npm:8.4.2"
|
||||
"@storybook/addon-toolbars": "npm:8.4.2"
|
||||
"@storybook/addon-viewport": "npm:8.4.2"
|
||||
"@storybook/addon-actions": "npm:8.4.6"
|
||||
"@storybook/addon-backgrounds": "npm:8.4.6"
|
||||
"@storybook/addon-controls": "npm:8.4.6"
|
||||
"@storybook/addon-docs": "npm:8.4.6"
|
||||
"@storybook/addon-highlight": "npm:8.4.6"
|
||||
"@storybook/addon-measure": "npm:8.4.6"
|
||||
"@storybook/addon-outline": "npm:8.4.6"
|
||||
"@storybook/addon-toolbars": "npm:8.4.6"
|
||||
"@storybook/addon-viewport": "npm:8.4.6"
|
||||
ts-dedent: "npm:^2.0.0"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/746470edd1f9ebbb9bd4f48461bc24141c215fe146b335efe14fbb289d381faf3935d55e4e25c251777b940caf827c06574062bb18bb1b95e2c9c85b89c8635a
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/b8fb83e018fcb1e8cad04b371af5f8ce9933e3a500a78a889715ecfe4efd9faa52acce2d0f97fb04fe9ae0898e661112816c052bfe9b5f01189938b122055a44
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-highlight@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/addon-highlight@npm:8.4.2"
|
||||
"@storybook/addon-highlight@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-highlight@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/global": "npm:^5.0.0"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/6838bab4434da65e85de70908f0ca09e9aa93facdb8fa6799100d711a55cbc69744c131f8994e910efd6bf74507bcc035f7ca4f3367c3003fc5799212160fc65
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/67a23a5e3b8f7740c7101e8fa886f3f9c6c61b6db3cb3430d2c805231f7ad170d2d926c12e7c9bfc4af327c5abac5b4155f4c0d70ea423b04704fe3def845acc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-measure@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/addon-measure@npm:8.4.2"
|
||||
"@storybook/addon-interactions@npm:^8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-interactions@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/global": "npm:^5.0.0"
|
||||
"@storybook/instrumenter": "npm:8.4.6"
|
||||
"@storybook/test": "npm:8.4.6"
|
||||
polished: "npm:^4.2.2"
|
||||
ts-dedent: "npm:^2.2.0"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/42e4bc2df354dba10217385687ac20fb355f4e1a2a7390812081d6b387151b67bca868211794e531c1e112dc4ce50c70dffa55c8f4338b0bd860d59363d58d5b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-measure@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-measure@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/global": "npm:^5.0.0"
|
||||
tiny-invariant: "npm:^1.3.1"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/3458cce88b41bb54f74f5affc610b07f486db07709ac13a1b84b7b17fb0d9c2b3fce9325b69a9f60a8d446ae0befc530a4de7d5dc133f4d818d438ff4378cf61
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/fd05b49fdb102a991fc696a0f75fde08d372b692778340ab2abc2c73fbd31a07dfa27a7a9d775dda7baaa9bd8a18972ed0bd86e9ce27948afb0305778f7b5a95
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-outline@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/addon-outline@npm:8.4.2"
|
||||
"@storybook/addon-outline@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-outline@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/global": "npm:^5.0.0"
|
||||
ts-dedent: "npm:^2.0.0"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/042693756b2d00e9454f544d35d1e6a638e7adc7e165c92a4a0c99578a0ff001357c54826fa0e8fe7dbedcd10e62b60045fd30e1cd2b4e3dff4521aece9e6426
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/62600a9f4164a8d91118d37cd7be4f4dd871e849a156ba7728f463bc2cfc5a8a233df09055dd5e5733a042fde7a63b08616cb3c61b26c363c1e2d4ce20d92584
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-themes@npm:^8.3.6":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/addon-themes@npm:8.4.2"
|
||||
"@storybook/addon-themes@npm:^8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-themes@npm:8.4.6"
|
||||
dependencies:
|
||||
ts-dedent: "npm:^2.0.0"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/53e93495011dd1c19d65370e3b9ce2b5ab9051558822311b5e03f36a7611210eaaee62c63866788e69ff96532a309d35626dcb02fbcee2f2963f4db1edd3a5d5
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/a20d84f1b8b72935b24a16dd1d859554398f4b391974ef04815e70c644901ff98910b8ed6d7415f939223853e4dfee61f466e7c3041c409195fd97f3176992c1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-toolbars@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/addon-toolbars@npm:8.4.2"
|
||||
"@storybook/addon-toolbars@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-toolbars@npm:8.4.6"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/f5808d3863867295475295423a397108d41b01ac6564b0a18241c2f1e3ecf9e67c4326c663917c72315f6c60f203dc0d0e93b4778af4e7071a047a6001e1eef5
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/6525e71aaa3870ae97d407b662323022ade98859f89975110f5fb4a1d3f34b6c918d47fcc8a6a271f4a77acfcaadc963a846a83ebc6c748b37df50422ad60e7e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/addon-viewport@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/addon-viewport@npm:8.4.2"
|
||||
"@storybook/addon-viewport@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/addon-viewport@npm:8.4.6"
|
||||
dependencies:
|
||||
memoizerific: "npm:^1.11.3"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/676dc421781afcb50598172d9a1391604e73b9d35989b23e33674ec81b16c5dbd123a6a43098134927e1d2ffb3353fd32231261025cfc5e50ebb1259329f8ec1
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/824438cc44a45f90748ac5f20ac148a36d975a94fa89504a583e0e1188de8c574e042ad3cd537bc16ddb30d4e44e90f5a63263239b13419aec5334e2ece18cd0
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/blocks@npm:8.4.2, @storybook/blocks@npm:^8.3.6":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/blocks@npm:8.4.2"
|
||||
"@storybook/blocks@npm:8.4.6, @storybook/blocks@npm:^8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/blocks@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/csf": "npm:^0.1.11"
|
||||
"@storybook/icons": "npm:^1.2.12"
|
||||
|
@ -1397,42 +1417,42 @@ __metadata:
|
|||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
storybook: ^8.4.2
|
||||
storybook: ^8.4.6
|
||||
peerDependenciesMeta:
|
||||
react:
|
||||
optional: true
|
||||
react-dom:
|
||||
optional: true
|
||||
checksum: 10c0/63cb3ed08742409041dca7fea3b476fb16675ddcc11b602ba4b20f61ab92993e15bc020e14e92398d4e2ea3bf62186274f5737c1c88ae26f9e717168f71441d5
|
||||
checksum: 10c0/36d79c3aeb3d27f4ba966d62302e13fc17fd7b450dbfbcf538adfc6df3cfecb13c92f9d2542871fa747a77d7c770e413b358623049135355fb01454d6eb52d9a
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/builder-vite@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/builder-vite@npm:8.4.2"
|
||||
"@storybook/builder-vite@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/builder-vite@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/csf-plugin": "npm:8.4.2"
|
||||
"@storybook/csf-plugin": "npm:8.4.6"
|
||||
browser-assert: "npm:^1.2.1"
|
||||
ts-dedent: "npm:^2.0.0"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
vite: ^4.0.0 || ^5.0.0
|
||||
checksum: 10c0/646f7cfbc77e7aaced8d2f0922e1b54662f6cb3c7602c5db97a419fd724033f8d68a332ebad9bf14641f7e7edec42797685bdfa24c666475f3bbeb23fe20f941
|
||||
storybook: ^8.4.6
|
||||
vite: ^4.0.0 || ^5.0.0 || ^6.0.0
|
||||
checksum: 10c0/36998ffea04023a9f634ebbafe0d1ab3bd3e7c7fec8e8e6c4caef3ce0c94ce01fa44f332f40d0053edb788548f95096baf8561cd35c23fe3c9bcfd872f74f631
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/components@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/components@npm:8.4.2"
|
||||
"@storybook/components@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/components@npm:8.4.6"
|
||||
peerDependencies:
|
||||
storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
|
||||
checksum: 10c0/36ffb5f73dceb481e76fa6e006118f382c23c8081cf47500f0eea8566e902a11d3fd219b599a9f622358f17652c445f71bc8d7a80e0d43f28cd85d60f7b4a15f
|
||||
checksum: 10c0/1622b2f12b6d18e5c495a623deb2930888b3e8b173a271cbe42a7cbd6e14e80b736c57792ea97d5269dff0e6c0db40385d3ea80ab6e46d4cb6e104aee6cac6bc
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/core@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/core@npm:8.4.2"
|
||||
"@storybook/core@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/core@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/csf": "npm:^0.1.11"
|
||||
better-opn: "npm:^3.0.2"
|
||||
|
@ -1450,18 +1470,18 @@ __metadata:
|
|||
peerDependenciesMeta:
|
||||
prettier:
|
||||
optional: true
|
||||
checksum: 10c0/75a9a9e00d98bb77d171a2738fdc0e9ab1cfbd760410b95c286368c7f25bbb756b61bd23b89d512707a02e450b81ecbdc72bf05e63fb18ea35509a2a806b0e21
|
||||
checksum: 10c0/1e30268eec18458dd78ed4b97fb12ac47b2c3cb41ffcbe9e9f5934b3f0c83b0bfcb0c0d508926344779383cc5260f992dcd534ffffab3f05425c7cee8c90687c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/csf-plugin@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/csf-plugin@npm:8.4.2"
|
||||
"@storybook/csf-plugin@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/csf-plugin@npm:8.4.6"
|
||||
dependencies:
|
||||
unplugin: "npm:^1.3.1"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/8fc0db319b8ebe6a445989cc0c5576c7186da086f84d5fad30615e1e527f31bcf562e12b4f31ec85e3fd188aa676116d4023232dcca4441c7c517cda0ac23bf0
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/d771f36ee768c6ff62ecd930c6ff64a4ba45bdbb7f7fb41e5f4ffd02204e3f54b17ed091049b265a6d371922bf599bfe749eb9deabfcd7e2b4fb5a5444655241
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -1491,43 +1511,55 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/manager-api@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/manager-api@npm:8.4.2"
|
||||
"@storybook/instrumenter@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/instrumenter@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/global": "npm:^5.0.0"
|
||||
"@vitest/utils": "npm:^2.1.1"
|
||||
peerDependencies:
|
||||
storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
|
||||
checksum: 10c0/306e16af4a4babf18d7b32335f974ac969a3f9139534f37e3ce238462f69f1ad52e3091a45bf76b1cbdd8f3cf989836c8433cad6cbb2c3eb4dcbc7ccb0f8ae82
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/602017872236124dc9dfa77d6bc2c5987d540063f15c7ace83bf91060d9343fdbe113a61cba44e17cae2247aeeb69875ebf45ff66ce9c28d364d2d3638eb3ec8
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/preview-api@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/preview-api@npm:8.4.2"
|
||||
"@storybook/manager-api@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/manager-api@npm:8.4.6"
|
||||
peerDependencies:
|
||||
storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
|
||||
checksum: 10c0/7b54c1962d27d32f29a3839660098ad8995cfcf31d4bde3662cff69d7a06cc4d315dad92f565901e3b0ebd7bf12fa8995cc625a71f13c34d82a4529412d8f83c
|
||||
checksum: 10c0/5921ec72df0be765bd398aa906186c9b121a8b3415a7e1a10014a8d17c44aec386b59de3d240017bfc925be00c40a4da8d26991b5fa39023f23ba8efe1b0d58e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/react-dom-shim@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/react-dom-shim@npm:8.4.2"
|
||||
"@storybook/preview-api@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/preview-api@npm:8.4.6"
|
||||
peerDependencies:
|
||||
storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
|
||||
checksum: 10c0/63967f4813c75e410634bff20189b5a670a061cfeeaa601ec07f0de82e2b4955af292836030d5a8432c3c7e48968285e121ed2bb55d2b5c70d17dbb4ada3c051
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/react-dom-shim@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/react-dom-shim@npm:8.4.6"
|
||||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
storybook: ^8.4.2
|
||||
checksum: 10c0/f4cc8d3cb557c8e84f62047680af926570f170a87aec7775830b91c4793c7afee84092ef6cd9c518dbd0ab9311139a4698f1477f35d21bc4d1462c6bd54105c5
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/b97c6faa3adc3efe1b7b6f5e38476e040c0a988b14db68e368d704c68f3f4d4bf7866b36607c118a0483242921b34944b5f5f72614d9852476476f6ead462e5c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/react-vite@npm:^8.3.6":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/react-vite@npm:8.4.2"
|
||||
"@storybook/react-vite@npm:^8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/react-vite@npm:8.4.6"
|
||||
dependencies:
|
||||
"@joshwooding/vite-plugin-react-docgen-typescript": "npm:0.3.0"
|
||||
"@joshwooding/vite-plugin-react-docgen-typescript": "npm:0.4.2"
|
||||
"@rollup/pluginutils": "npm:^5.0.2"
|
||||
"@storybook/builder-vite": "npm:8.4.2"
|
||||
"@storybook/react": "npm:8.4.2"
|
||||
"@storybook/builder-vite": "npm:8.4.6"
|
||||
"@storybook/react": "npm:8.4.6"
|
||||
find-up: "npm:^5.0.0"
|
||||
magic-string: "npm:^0.30.0"
|
||||
react-docgen: "npm:^7.0.0"
|
||||
|
@ -1536,43 +1568,101 @@ __metadata:
|
|||
peerDependencies:
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
storybook: ^8.4.2
|
||||
vite: ^4.0.0 || ^5.0.0
|
||||
checksum: 10c0/7e04112b0678a2bfd9fb913eb9161055fdb30d6ee34983294632eaae72067a16727e84801bede7b76cd7f7e0c6005021011432ea394c1a82fd73de5c6fb7b567
|
||||
storybook: ^8.4.6
|
||||
vite: ^4.0.0 || ^5.0.0 || ^6.0.0
|
||||
checksum: 10c0/9f81a19461dbbf11932a13f8fb611dbcd95fbfa695ee5536daf7e078bf0feb5ddda2738606073826131e3fee710e230dce9042e3f7f985203392376aa8407643
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/react@npm:8.4.2, @storybook/react@npm:^8.3.6":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/react@npm:8.4.2"
|
||||
"@storybook/react@npm:8.4.6, @storybook/react@npm:^8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/react@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/components": "npm:8.4.2"
|
||||
"@storybook/components": "npm:8.4.6"
|
||||
"@storybook/global": "npm:^5.0.0"
|
||||
"@storybook/manager-api": "npm:8.4.2"
|
||||
"@storybook/preview-api": "npm:8.4.2"
|
||||
"@storybook/react-dom-shim": "npm:8.4.2"
|
||||
"@storybook/theming": "npm:8.4.2"
|
||||
"@storybook/manager-api": "npm:8.4.6"
|
||||
"@storybook/preview-api": "npm:8.4.6"
|
||||
"@storybook/react-dom-shim": "npm:8.4.6"
|
||||
"@storybook/theming": "npm:8.4.6"
|
||||
peerDependencies:
|
||||
"@storybook/test": 8.4.2
|
||||
"@storybook/test": 8.4.6
|
||||
react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0-beta
|
||||
storybook: ^8.4.2
|
||||
storybook: ^8.4.6
|
||||
typescript: ">= 4.2.x"
|
||||
peerDependenciesMeta:
|
||||
"@storybook/test":
|
||||
optional: true
|
||||
typescript:
|
||||
optional: true
|
||||
checksum: 10c0/a5ce045dae71c2a039c1ac4411c07b4a51574a6f607c6c6f105e87147410b32e7d882b3f225d6fa78ddc29423881aee76727826d2b960a61f913f7d849fdcc1f
|
||||
checksum: 10c0/1441f8ab3be91757647c6b1a05eb1ef0d78a454ffd14b01a14fdde00e92a8be8fc7c8408c4670b46bc20a5a04995514f0890e98ed6ee35c362ff36141da02f02
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/theming@npm:8.4.2":
|
||||
version: 8.4.2
|
||||
resolution: "@storybook/theming@npm:8.4.2"
|
||||
"@storybook/test@npm:8.4.6, @storybook/test@npm:^8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/test@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/csf": "npm:^0.1.11"
|
||||
"@storybook/global": "npm:^5.0.0"
|
||||
"@storybook/instrumenter": "npm:8.4.6"
|
||||
"@testing-library/dom": "npm:10.4.0"
|
||||
"@testing-library/jest-dom": "npm:6.5.0"
|
||||
"@testing-library/user-event": "npm:14.5.2"
|
||||
"@vitest/expect": "npm:2.0.5"
|
||||
"@vitest/spy": "npm:2.0.5"
|
||||
peerDependencies:
|
||||
storybook: ^8.4.6
|
||||
checksum: 10c0/fbf7c2ac7773a7fe18145876eb67491ce90b000ba5f8e364a319569e56d56e706fdd1c7ef24d3ab2ffa3dfcdb92377d8050c8ffbd457d2d8b613aba2a4845a04
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@storybook/theming@npm:8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "@storybook/theming@npm:8.4.6"
|
||||
peerDependencies:
|
||||
storybook: ^8.2.0 || ^8.3.0-0 || ^8.4.0-0 || ^8.5.0-0 || ^8.6.0-0
|
||||
checksum: 10c0/8765a25952273f87f65018159228fa448a0bb6fa38486650344ddc076cd895546ab3b88d35a6e7f80d3223635e28d59f82510922c589a36a7c6afc33c5bcc0d7
|
||||
checksum: 10c0/7d9c8e5ef2c1d974cd5258301350a2345890326e7be7a5ed6bdd0db70fd1648c0bbb8ee1d905f8e66fa57b75c47aefe7ec9772ec0bfb9691d127dcc19286e4c9
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@testing-library/dom@npm:10.4.0":
|
||||
version: 10.4.0
|
||||
resolution: "@testing-library/dom@npm:10.4.0"
|
||||
dependencies:
|
||||
"@babel/code-frame": "npm:^7.10.4"
|
||||
"@babel/runtime": "npm:^7.12.5"
|
||||
"@types/aria-query": "npm:^5.0.1"
|
||||
aria-query: "npm:5.3.0"
|
||||
chalk: "npm:^4.1.0"
|
||||
dom-accessibility-api: "npm:^0.5.9"
|
||||
lz-string: "npm:^1.5.0"
|
||||
pretty-format: "npm:^27.0.2"
|
||||
checksum: 10c0/0352487720ecd433400671e773df0b84b8268fb3fe8e527cdfd7c11b1365b398b4e0eddba6e7e0c85e8d615f48257753283fccec41f6b986fd6c85f15eb5f84f
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@testing-library/jest-dom@npm:6.5.0":
|
||||
version: 6.5.0
|
||||
resolution: "@testing-library/jest-dom@npm:6.5.0"
|
||||
dependencies:
|
||||
"@adobe/css-tools": "npm:^4.4.0"
|
||||
aria-query: "npm:^5.0.0"
|
||||
chalk: "npm:^3.0.0"
|
||||
css.escape: "npm:^1.5.1"
|
||||
dom-accessibility-api: "npm:^0.6.3"
|
||||
lodash: "npm:^4.17.21"
|
||||
redent: "npm:^3.0.0"
|
||||
checksum: 10c0/fd5936a547f04608d8de15a7de3ae26516f21023f8f45169b10c8c8847015fd20ec259b7309f08aa1031bcbc37c6e5e6f532d1bb85ef8f91bad654193ec66a4c
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@testing-library/user-event@npm:14.5.2":
|
||||
version: 14.5.2
|
||||
resolution: "@testing-library/user-event@npm:14.5.2"
|
||||
peerDependencies:
|
||||
"@testing-library/dom": ">=7.21.4"
|
||||
checksum: 10c0/68a0c2aa28a3c8e6eb05cafee29705438d7d8a9427423ce5064d44f19c29e89b5636de46dd2f28620fb10abba75c67130185bbc3aa23ac1163a227a5f36641e1
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -1607,6 +1697,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/aria-query@npm:^5.0.1":
|
||||
version: 5.0.4
|
||||
resolution: "@types/aria-query@npm:5.0.4"
|
||||
checksum: 10c0/dc667bc6a3acc7bba2bccf8c23d56cb1f2f4defaa704cfef595437107efaa972d3b3db9ec1d66bc2711bfc35086821edd32c302bffab36f2e79b97f312069f08
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/babel__core@npm:^7.18.0":
|
||||
version: 7.20.5
|
||||
resolution: "@types/babel__core@npm:7.20.5"
|
||||
|
@ -1662,16 +1759,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/glob@npm:^7.1.3":
|
||||
version: 7.2.0
|
||||
resolution: "@types/glob@npm:7.2.0"
|
||||
dependencies:
|
||||
"@types/minimatch": "npm:*"
|
||||
"@types/node": "npm:*"
|
||||
checksum: 10c0/a8eb5d5cb5c48fc58c7ca3ff1e1ddf771ee07ca5043da6e4871e6757b4472e2e73b4cfef2644c38983174a4bc728c73f8da02845c28a1212f98cabd293ecae98
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/mdx@npm:^2.0.0":
|
||||
version: 2.0.13
|
||||
resolution: "@types/mdx@npm:2.0.13"
|
||||
|
@ -1679,14 +1766,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/minimatch@npm:*":
|
||||
version: 5.1.2
|
||||
resolution: "@types/minimatch@npm:5.1.2"
|
||||
checksum: 10c0/83cf1c11748891b714e129de0585af4c55dd4c2cafb1f1d5233d79246e5e1e19d1b5ad9e8db449667b3ffa2b6c80125c429dbee1054e9efb45758dbc4e118562
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@types/node@npm:*, @types/node@npm:^22.7.7":
|
||||
"@types/node@npm:^22.7.7":
|
||||
version: 22.9.0
|
||||
resolution: "@types/node@npm:22.9.0"
|
||||
dependencies:
|
||||
|
@ -1716,6 +1796,18 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/expect@npm:2.0.5":
|
||||
version: 2.0.5
|
||||
resolution: "@vitest/expect@npm:2.0.5"
|
||||
dependencies:
|
||||
"@vitest/spy": "npm:2.0.5"
|
||||
"@vitest/utils": "npm:2.0.5"
|
||||
chai: "npm:^5.1.1"
|
||||
tinyrainbow: "npm:^1.2.0"
|
||||
checksum: 10c0/08cb1b0f106d16a5b60db733e3d436fa5eefc68571488eb570dfe4f599f214ab52e4342273b03dbe12331cc6c0cdc325ac6c94f651ad254cd62f3aa0e3d185aa
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/expect@npm:2.1.4":
|
||||
version: 2.1.4
|
||||
resolution: "@vitest/expect@npm:2.1.4"
|
||||
|
@ -1747,6 +1839,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/pretty-format@npm:2.0.5":
|
||||
version: 2.0.5
|
||||
resolution: "@vitest/pretty-format@npm:2.0.5"
|
||||
dependencies:
|
||||
tinyrainbow: "npm:^1.2.0"
|
||||
checksum: 10c0/236c0798c5170a0b5ad5d4bd06118533738e820b4dd30079d8fbcb15baee949d41c60f42a9f769906c4a5ce366d7ef11279546070646c0efc03128c220c31f37
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/pretty-format@npm:2.1.4, @vitest/pretty-format@npm:^2.1.4":
|
||||
version: 2.1.4
|
||||
resolution: "@vitest/pretty-format@npm:2.1.4"
|
||||
|
@ -1756,6 +1857,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/pretty-format@npm:2.1.8":
|
||||
version: 2.1.8
|
||||
resolution: "@vitest/pretty-format@npm:2.1.8"
|
||||
dependencies:
|
||||
tinyrainbow: "npm:^1.2.0"
|
||||
checksum: 10c0/1dc5c9b1c7c7e78e46a2a16033b6b20be05958bbebc5a5b78f29e32718c80252034804fccd23f34db6b3583239db47e68fc5a8e41942c54b8047cc3b4133a052
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/runner@npm:2.1.4":
|
||||
version: 2.1.4
|
||||
resolution: "@vitest/runner@npm:2.1.4"
|
||||
|
@ -1777,6 +1887,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/spy@npm:2.0.5":
|
||||
version: 2.0.5
|
||||
resolution: "@vitest/spy@npm:2.0.5"
|
||||
dependencies:
|
||||
tinyspy: "npm:^3.0.0"
|
||||
checksum: 10c0/70634c21921eb271b54d2986c21d7ab6896a31c0f4f1d266940c9bafb8ac36237846d6736638cbf18b958bd98e5261b158a6944352742accfde50b7818ff655e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/spy@npm:2.1.4":
|
||||
version: 2.1.4
|
||||
resolution: "@vitest/spy@npm:2.1.4"
|
||||
|
@ -1786,6 +1905,18 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/utils@npm:2.0.5":
|
||||
version: 2.0.5
|
||||
resolution: "@vitest/utils@npm:2.0.5"
|
||||
dependencies:
|
||||
"@vitest/pretty-format": "npm:2.0.5"
|
||||
estree-walker: "npm:^3.0.3"
|
||||
loupe: "npm:^3.1.1"
|
||||
tinyrainbow: "npm:^1.2.0"
|
||||
checksum: 10c0/0d1de748298f07a50281e1ba058b05dcd58da3280c14e6f016265e950bd79adab6b97822de8f0ea82d3070f585654801a9b1bcf26db4372e51cf7746bf86d73b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/utils@npm:2.1.4":
|
||||
version: 2.1.4
|
||||
resolution: "@vitest/utils@npm:2.1.4"
|
||||
|
@ -1797,6 +1928,17 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@vitest/utils@npm:^2.1.1":
|
||||
version: 2.1.8
|
||||
resolution: "@vitest/utils@npm:2.1.8"
|
||||
dependencies:
|
||||
"@vitest/pretty-format": "npm:2.1.8"
|
||||
loupe: "npm:^3.1.2"
|
||||
tinyrainbow: "npm:^1.2.0"
|
||||
checksum: 10c0/d4a29ecd8f6c24c790e4c009f313a044d89e664e331bc9c3cfb57fe1380fb1d2999706dbbfc291f067d6c489602e76d00435309fbc906197c0d01f831ca17d64
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"@xmldom/xmldom@npm:^0.8.10":
|
||||
version: 0.8.10
|
||||
resolution: "@xmldom/xmldom@npm:0.8.10"
|
||||
|
@ -1931,6 +2073,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ansi-styles@npm:^5.0.0":
|
||||
version: 5.2.0
|
||||
resolution: "ansi-styles@npm:5.2.0"
|
||||
checksum: 10c0/9c4ca80eb3c2fb7b33841c210d2f20807f40865d27008d7c3f707b7f95cab7d67462a565e2388ac3285b71cb3d9bb2173de8da37c57692a362885ec34d6e27df
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ansi-styles@npm:^6.1.0":
|
||||
version: 6.2.1
|
||||
resolution: "ansi-styles@npm:6.2.1"
|
||||
|
@ -1969,6 +2118,22 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"aria-query@npm:5.3.0":
|
||||
version: 5.3.0
|
||||
resolution: "aria-query@npm:5.3.0"
|
||||
dependencies:
|
||||
dequal: "npm:^2.0.3"
|
||||
checksum: 10c0/2bff0d4eba5852a9dd578ecf47eaef0e82cc52569b48469b0aac2db5145db0b17b7a58d9e01237706d1e14b7a1b0ac9b78e9c97027ad97679dd8f91b85da1469
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"aria-query@npm:^5.0.0":
|
||||
version: 5.3.2
|
||||
resolution: "aria-query@npm:5.3.2"
|
||||
checksum: 10c0/003c7e3e2cff5540bf7a7893775fc614de82b0c5dde8ae823d47b7a28a9d4da1f7ed85f340bdb93d5649caa927755f0e31ecc7ab63edfdfc00c8ef07e505e03e
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"arr-diff@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "arr-diff@npm:4.0.0"
|
||||
|
@ -2469,7 +2634,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chai@npm:^5.1.2":
|
||||
"chai@npm:^5.1.1, chai@npm:^5.1.2":
|
||||
version: 5.1.2
|
||||
resolution: "chai@npm:5.1.2"
|
||||
dependencies:
|
||||
|
@ -2493,7 +2658,17 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chalk@npm:^4.1.2":
|
||||
"chalk@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "chalk@npm:3.0.0"
|
||||
dependencies:
|
||||
ansi-styles: "npm:^4.1.0"
|
||||
supports-color: "npm:^7.1.0"
|
||||
checksum: 10c0/ee650b0a065b3d7a6fda258e75d3a86fc8e4effa55871da730a9e42ccb035bf5fd203525e5a1ef45ec2582ecc4f65b47eb11357c526b84dd29a14fb162c414d2
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"chalk@npm:^4.1.0, chalk@npm:^4.1.2":
|
||||
version: 4.1.2
|
||||
resolution: "chalk@npm:4.1.2"
|
||||
dependencies:
|
||||
|
@ -3071,6 +3246,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"css.escape@npm:^1.5.1":
|
||||
version: 1.5.1
|
||||
resolution: "css.escape@npm:1.5.1"
|
||||
checksum: 10c0/5e09035e5bf6c2c422b40c6df2eb1529657a17df37fda5d0433d722609527ab98090baf25b13970ca754079a0f3161dd3dfc0e743563ded8cfa0749d861c1525
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"css@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "css@npm:3.0.0"
|
||||
|
@ -3304,7 +3486,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dequal@npm:^2.0.2":
|
||||
"dequal@npm:^2.0.2, dequal@npm:^2.0.3":
|
||||
version: 2.0.3
|
||||
resolution: "dequal@npm:2.0.3"
|
||||
checksum: 10c0/f98860cdf58b64991ae10205137c0e97d384c3a4edc7f807603887b7c4b850af1224a33d88012009f150861cbee4fa2d322c4cc04b9313bee312e47f6ecaa888
|
||||
|
@ -3378,6 +3560,20 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dom-accessibility-api@npm:^0.5.9":
|
||||
version: 0.5.16
|
||||
resolution: "dom-accessibility-api@npm:0.5.16"
|
||||
checksum: 10c0/b2c2eda4fae568977cdac27a9f0c001edf4f95a6a6191dfa611e3721db2478d1badc01db5bb4fa8a848aeee13e442a6c2a4386d65ec65a1436f24715a2f8d053
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dom-accessibility-api@npm:^0.6.3":
|
||||
version: 0.6.3
|
||||
resolution: "dom-accessibility-api@npm:0.6.3"
|
||||
checksum: 10c0/10bee5aa514b2a9a37c87cd81268db607a2e933a050074abc2f6fa3da9080ebed206a320cbc123567f2c3087d22292853bdfdceaffdd4334ffe2af9510b29360
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"dom-helpers@npm:^5.1.3":
|
||||
version: 5.2.1
|
||||
resolution: "dom-helpers@npm:5.2.1"
|
||||
|
@ -4301,11 +4497,13 @@ __metadata:
|
|||
"@penpot/svgo": "penpot/svgo#c6fba7a4dcfbc27b643e7fc0c94fc98cf680b77b"
|
||||
"@penpot/text-editor": "portal:./text-editor"
|
||||
"@playwright/test": "npm:1.48.1"
|
||||
"@storybook/addon-essentials": "npm:^8.3.6"
|
||||
"@storybook/addon-themes": "npm:^8.3.6"
|
||||
"@storybook/blocks": "npm:^8.3.6"
|
||||
"@storybook/react": "npm:^8.3.6"
|
||||
"@storybook/react-vite": "npm:^8.3.6"
|
||||
"@storybook/addon-essentials": "npm:^8.4.6"
|
||||
"@storybook/addon-interactions": "npm:^8.4.6"
|
||||
"@storybook/addon-themes": "npm:^8.4.6"
|
||||
"@storybook/blocks": "npm:^8.4.6"
|
||||
"@storybook/react": "npm:^8.4.6"
|
||||
"@storybook/react-vite": "npm:^8.4.6"
|
||||
"@storybook/test": "npm:^8.4.6"
|
||||
"@tokens-studio/sd-transforms": "npm:^0.16.1"
|
||||
"@types/node": "npm:^22.7.7"
|
||||
autoprefixer: "npm:^10.4.20"
|
||||
|
@ -4358,7 +4556,7 @@ __metadata:
|
|||
sax: "npm:^1.4.1"
|
||||
shadow-cljs: "npm:2.28.18"
|
||||
source-map-support: "npm:^0.5.21"
|
||||
storybook: "npm:^8.3.6"
|
||||
storybook: "npm:^8.4.6"
|
||||
style-dictionary: "npm:4.0.0-prerelease.34"
|
||||
svg-sprite: "npm:^2.0.4"
|
||||
tdigest: "npm:^0.1.2"
|
||||
|
@ -4550,17 +4748,6 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob-promise@npm:^4.2.0":
|
||||
version: 4.2.2
|
||||
resolution: "glob-promise@npm:4.2.2"
|
||||
dependencies:
|
||||
"@types/glob": "npm:^7.1.3"
|
||||
peerDependencies:
|
||||
glob: ^7.1.6
|
||||
checksum: 10c0/3eb01bed2901539365df6a4d27800afb8788840647d01f9bf3500b3de756597f2ff4b8c823971ace34db228c83159beca459dc42a70968d4e9c8200ed2cc96bd
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob@npm:^10.2.2, glob@npm:^10.3.10, glob@npm:^10.3.3, glob@npm:^10.4.2":
|
||||
version: 10.4.5
|
||||
resolution: "glob@npm:10.4.5"
|
||||
|
@ -4593,7 +4780,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"glob@npm:^7.1.3, glob@npm:^7.2.0, glob@npm:^7.2.3":
|
||||
"glob@npm:^7.1.3, glob@npm:^7.2.3":
|
||||
version: 7.2.3
|
||||
resolution: "glob@npm:7.2.3"
|
||||
dependencies:
|
||||
|
@ -5695,7 +5882,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"loupe@npm:^3.1.0, loupe@npm:^3.1.2":
|
||||
"loupe@npm:^3.1.0, loupe@npm:^3.1.1, loupe@npm:^3.1.2":
|
||||
version: 3.1.2
|
||||
resolution: "loupe@npm:3.1.2"
|
||||
checksum: 10c0/b13c02e3ddd6a9d5f8bf84133b3242de556512d824dddeea71cce2dbd6579c8f4d672381c4e742d45cf4423d0701765b4a6e5fbc24701def16bc2b40f8daa96a
|
||||
|
@ -5741,6 +5928,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"lz-string@npm:^1.5.0":
|
||||
version: 1.5.0
|
||||
resolution: "lz-string@npm:1.5.0"
|
||||
bin:
|
||||
lz-string: bin/bin.js
|
||||
checksum: 10c0/36128e4de34791838abe979b19927c26e67201ca5acf00880377af7d765b38d1c60847e01c5ec61b1a260c48029084ab3893a3925fd6e48a04011364b089991b
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"magic-string@npm:^0.27.0":
|
||||
version: 0.27.0
|
||||
resolution: "magic-string@npm:0.27.0"
|
||||
|
@ -5953,7 +6149,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"min-indent@npm:^1.0.1":
|
||||
"min-indent@npm:^1.0.0, min-indent@npm:^1.0.1":
|
||||
version: 1.0.1
|
||||
resolution: "min-indent@npm:1.0.1"
|
||||
checksum: 10c0/7e207bd5c20401b292de291f02913230cb1163abca162044f7db1d951fa245b174dc00869d40dd9a9f32a885ad6a5f3e767ee104cf278f399cb4e92d3f582d5c
|
||||
|
@ -7003,6 +7199,17 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pretty-format@npm:^27.0.2":
|
||||
version: 27.5.1
|
||||
resolution: "pretty-format@npm:27.5.1"
|
||||
dependencies:
|
||||
ansi-regex: "npm:^5.0.1"
|
||||
ansi-styles: "npm:^5.0.0"
|
||||
react-is: "npm:^17.0.1"
|
||||
checksum: 10c0/0cbda1031aa30c659e10921fa94e0dd3f903ecbbbe7184a729ad66f2b6e7f17891e8c7d7654c458fa4ccb1a411ffb695b4f17bbcd3fe075fabe181027c4040ed
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"pretty-time@npm:^1.1.0":
|
||||
version: 1.1.0
|
||||
resolution: "pretty-time@npm:1.1.0"
|
||||
|
@ -7254,6 +7461,13 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-is@npm:^17.0.1":
|
||||
version: 17.0.2
|
||||
resolution: "react-is@npm:17.0.2"
|
||||
checksum: 10c0/2bdb6b93fbb1820b024b496042cce405c57e2f85e777c9aabd55f9b26d145408f9f74f5934676ffdc46f3dcff656d78413a6e43968e7b3f92eea35b3052e9053
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"react-lifecycles-compat@npm:^3.0.4":
|
||||
version: 3.0.4
|
||||
resolution: "react-lifecycles-compat@npm:3.0.4"
|
||||
|
@ -7373,6 +7587,16 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"redent@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "redent@npm:3.0.0"
|
||||
dependencies:
|
||||
indent-string: "npm:^4.0.0"
|
||||
strip-indent: "npm:^3.0.0"
|
||||
checksum: 10c0/d64a6b5c0b50eb3ddce3ab770f866658a2b9998c678f797919ceb1b586bab9259b311407280bd80b804e2a7c7539b19238ae6a2a20c843f1a7fcff21d48c2eae
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"regenerator-runtime@npm:^0.14.0":
|
||||
version: 0.14.1
|
||||
resolution: "regenerator-runtime@npm:0.14.1"
|
||||
|
@ -8288,11 +8512,11 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"storybook@npm:^8.3.6":
|
||||
version: 8.4.2
|
||||
resolution: "storybook@npm:8.4.2"
|
||||
"storybook@npm:^8.4.6":
|
||||
version: 8.4.6
|
||||
resolution: "storybook@npm:8.4.6"
|
||||
dependencies:
|
||||
"@storybook/core": "npm:8.4.2"
|
||||
"@storybook/core": "npm:8.4.6"
|
||||
peerDependencies:
|
||||
prettier: ^2 || ^3
|
||||
peerDependenciesMeta:
|
||||
|
@ -8302,7 +8526,7 @@ __metadata:
|
|||
getstorybook: ./bin/index.cjs
|
||||
sb: ./bin/index.cjs
|
||||
storybook: ./bin/index.cjs
|
||||
checksum: 10c0/54791f44de53d465a74c44ec16255ebe5248156eee54b768fdcc12a7556e1b6e2a23c9c5c5eec0c3fcc71c3820398999ede5042f711a851b0ca9c71e65c8ab19
|
||||
checksum: 10c0/e15249718c1efab3d3d05f3152df28fc8f7e2e988bf7414cd4abf2adfb5d6c3b802f05dad5be0521c30d0ba43e55abf516e6f874b0671e0d1e84a7096cb47d3d
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
|
@ -8479,6 +8703,15 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"strip-indent@npm:^3.0.0":
|
||||
version: 3.0.0
|
||||
resolution: "strip-indent@npm:3.0.0"
|
||||
dependencies:
|
||||
min-indent: "npm:^1.0.0"
|
||||
checksum: 10c0/ae0deaf41c8d1001c5d4fbe16cb553865c1863da4fae036683b474fa926af9fc121e155cb3fc57a68262b2ae7d5b8420aa752c97a6428c315d00efe2a3875679
|
||||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"strip-indent@npm:^4.0.0":
|
||||
version: 4.0.0
|
||||
resolution: "strip-indent@npm:4.0.0"
|
||||
|
@ -8745,7 +8978,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"tinyspy@npm:^3.0.2":
|
||||
"tinyspy@npm:^3.0.0, tinyspy@npm:^3.0.2":
|
||||
version: 3.0.2
|
||||
resolution: "tinyspy@npm:3.0.2"
|
||||
checksum: 10c0/55ffad24e346622b59292e097c2ee30a63919d5acb7ceca87fc0d1c223090089890587b426e20054733f97a58f20af2c349fb7cc193697203868ab7ba00bcea0
|
||||
|
@ -8861,7 +9094,7 @@ __metadata:
|
|||
languageName: node
|
||||
linkType: hard
|
||||
|
||||
"ts-dedent@npm:^2.0.0":
|
||||
"ts-dedent@npm:^2.0.0, ts-dedent@npm:^2.2.0":
|
||||
version: 2.2.0
|
||||
resolution: "ts-dedent@npm:2.2.0"
|
||||
checksum: 10c0/175adea838468cc2ff7d5e97f970dcb798bbcb623f29c6088cb21aa2880d207c5784be81ab1741f56b9ac37840cbaba0c0d79f7f8b67ffe61c02634cafa5c303
|
||||
|
|
25
render-wasm/README.md
Normal file
25
render-wasm/README.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
# render-wasm
|
||||
|
||||
Canvas-based WebAssembly render engine for Penpot.
|
||||
|
||||
This is a Rust crate that targets [Emscripten](https://emscripten.org/) (`wasm32-unknown-emscripten`). Underneath, it uses Skia via [custom binaries](https://github.com/penpot/skia-binaries/releases/) of the [rust-skia crate](https://github.com/rust-skia/rust-skia).
|
||||
|
||||
## How to build
|
||||
|
||||
With the [Penpot Development Environment](https://help.penpot.app/technical-guide/developer/devenv/) running, create a new tab in the tmux.
|
||||
|
||||
```sh
|
||||
cd penpot/render-wasm
|
||||
./build
|
||||
```
|
||||
|
||||
The build script will compile the project and copy the `.js` and `.wasm` files to their correct location within the frontend app.
|
||||
|
||||
Edit your local `frontend/resources/public/js/config.js` to add the following flags:
|
||||
|
||||
- `enable-feature-render-wasm` to enable this render engine.
|
||||
- `enable-render-wasm-dpr` (optional), to enable using the device pixel ratio.
|
||||
|
||||
## Docs
|
||||
|
||||
- [Serialization](./docs/serialization.md)
|
41
render-wasm/docs/serialization.md
Normal file
41
render-wasm/docs/serialization.md
Normal file
|
@ -0,0 +1,41 @@
|
|||
# Serialization
|
||||
|
||||
## Paths
|
||||
|
||||
Paths are made of segments of **28 bytes** each. The layout (assuming positions in a `Uint8Array`) is the following:
|
||||
|
||||
| Offset | Length (bytes) | Data Type | Field |
|
||||
| ------ | -------------- | --------- | ------- |
|
||||
| 0 | 2 | `u16` | Command |
|
||||
| 2 | 2 | `u16` | Flags |
|
||||
| 4 | 4 | `f32` | `c1_x` |
|
||||
| 8 | 4 | `f32` | `c1_y` |
|
||||
| 12 | 4 | `f32` | `c2_x` |
|
||||
| 16 | 4 | `f32` | `c2_y` |
|
||||
| 20 | 4 | `f32` | `x` |
|
||||
| 24 | 4 | `f32` | `y` |
|
||||
|
||||
**Command** can be one of these values:
|
||||
|
||||
- `:move-to`: `1`
|
||||
- `:line-to`: `2`
|
||||
- `:curve-to`: `3`
|
||||
- `:close-path`: `4`
|
||||
|
||||
**Flags** is not being used at the moment.
|
||||
|
||||
## Gradient stops
|
||||
|
||||
Gradient stops are serialized in a `Uint8Array`, each stop taking **5 bytes**.
|
||||
|
||||
| Offset | Length (bytes) | Data Type | Field |
|
||||
| ------ | -------------- | --------- | ----------- |
|
||||
| 0 | 1 | `u8` | Red |
|
||||
| 1 | 1 | `u8` | Green |
|
||||
| 2 | 1 | `u8` | Blue |
|
||||
| 3 | 1 | `u8` | Alpha |
|
||||
| 4 | 1 | `u8` | Stop Offset |
|
||||
|
||||
**Red**, **Green**, **Blue** and **Alpha** are the RGBA components of the stop.
|
||||
|
||||
**Stop offset** is the offset, being integer values ranging from `0` to `100` (both inclusive).
|
|
@ -49,6 +49,14 @@ pub extern "C" fn set_render_options(debug: u32, dpr: f32) {
|
|||
render_state.set_dpr(dpr);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn set_canvas_background(raw_color: u32) {
|
||||
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
|
||||
|
||||
let color = skia::Color::new(raw_color);
|
||||
state.set_background_color(color);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn render() {
|
||||
let state = unsafe { STATE.as_mut() }.expect("got an invalid state pointer");
|
||||
|
|
|
@ -49,6 +49,7 @@ pub(crate) struct RenderState {
|
|||
options: RenderOptions,
|
||||
pub viewbox: Viewbox,
|
||||
images: ImageStore,
|
||||
background_color: skia::Color,
|
||||
}
|
||||
|
||||
impl RenderState {
|
||||
|
@ -72,6 +73,7 @@ impl RenderState {
|
|||
options: RenderOptions::default(),
|
||||
viewbox: Viewbox::new(width as f32, height as f32),
|
||||
images: ImageStore::new(),
|
||||
background_color: skia::Color::TRANSPARENT,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -97,6 +99,11 @@ impl RenderState {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_background_color(&mut self, color: skia::Color) {
|
||||
self.background_color = color;
|
||||
let _ = self.render_all_from_cache();
|
||||
}
|
||||
|
||||
pub fn resize(&mut self, width: i32, height: i32) {
|
||||
let dpr_width = (width as f32 * self.options.dpr()).floor() as i32;
|
||||
let dpr_height = (height as f32 * self.options.dpr()).floor() as i32;
|
||||
|
@ -136,7 +143,7 @@ impl RenderState {
|
|||
.reset_matrix();
|
||||
self.final_surface
|
||||
.canvas()
|
||||
.clear(skia::Color::TRANSPARENT)
|
||||
.clear(self.background_color)
|
||||
.reset_matrix();
|
||||
self.debug_surface
|
||||
.canvas()
|
||||
|
|
|
@ -1,4 +1,6 @@
|
|||
use std::collections::HashMap;
|
||||
|
||||
use skia_safe as skia;
|
||||
use uuid::Uuid;
|
||||
|
||||
use crate::render::RenderState;
|
||||
|
@ -57,4 +59,9 @@ impl<'a> State<'a> {
|
|||
pub fn current_shape(&'a mut self) -> Option<&'a mut Shape> {
|
||||
self.current_shape.as_deref_mut()
|
||||
}
|
||||
|
||||
pub fn set_background_color(&mut self, color: skia::Color) {
|
||||
self.render_state.set_background_color(color);
|
||||
self.render_all(true);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue