@thinkpixellab-public/px-vue 5.0.3 → 5.2.0
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.
- package/README.md +10 -15
- package/bases/PxBaseScroll.vue +0 -1
- package/components/PxColorPanel.vue +2 -1
- package/components/PxSelectionBar.vue +0 -1
- package/components/PxValidator.vue +0 -1
- package/composables/loadGsap.js +10 -10
- package/package.json +60 -42
- package/plugins/common-client.js +0 -3
- package/plugins/common.js +0 -3
- package/utils/SharedHeightManager.js +2 -2
- package/utils/cardGridLayoutHelper.js +1 -1
- package/utils/scrollWatcher.js +6 -6
- package/utils/smootherCorners.js +33 -38
- package/.eslintrc.js +0 -14
- package/.prettierrc.json +0 -10
- package/.storybook/main.js +0 -26
- package/.storybook/manager-head.html +0 -0
- package/.storybook/manager.js +0 -6
- package/.storybook/preview-head.html +0 -3
- package/.storybook/preview.js +0 -26
- package/.storybook/preview.scss +0 -3
- package/.storybook/px-styles.config.scss +0 -26
- package/babel.config.js +0 -16
- package/chromatic.config.json +0 -5
- package/dev/data/fruits.js +0 -59
- package/dev/data/random.js +0 -13
- package/dev/demos/Demo-PxBaseDrag.vue +0 -94
- package/dev/demos/Demo-PxCardGrid.vue +0 -50
- package/dev/demos/Demo-PxContain.vue +0 -106
- package/dev/demos/Demo-PxFlip.vue +0 -104
- package/dev/demos/Demo-PxFloat.vue +0 -105
- package/dev/demos/Demo-PxMenu.vue +0 -94
- package/dev/demos/Demo-PxPivot.vue +0 -55
- package/dev/demos/Demo-PxSideDrawer.vue +0 -62
- package/dev/demos/Demo-PxSlideTransition.vue +0 -84
- package/dev/demos/Demo-PxSlides.vue +0 -142
- package/dev/demos/Demo-PxStylesPreview.vue +0 -41
- package/dev/demos/Demo-PxSwiper.vue +0 -36
- package/dev/demos/DemoPicker.vue +0 -77
- package/dev/dev.vue +0 -64
- package/dev/serve.js +0 -17
- package/stories/Intro.mdx +0 -1
- package/stories/PxAnimate.stories.js +0 -184
- package/stories/PxArrow.stories.js +0 -74
- package/stories/PxArrowScroller.stories.js +0 -38
- package/stories/PxAspect.stories.js +0 -66
- package/stories/PxAutoClamp.stories.js +0 -47
- package/stories/PxBackgroundFader.stories.js +0 -42
- package/stories/PxBalancedText.stories.js +0 -66
- package/stories/PxButton.stories.js +0 -83
- package/stories/PxCalendar.stories.js +0 -36
- package/stories/PxCard.stories.js +0 -31
- package/stories/PxCardGrid.stories.js +0 -60
- package/stories/PxClock.stories.js +0 -36
- package/stories/PxCodeSample.stories.js +0 -53
- package/stories/PxColorPalette.stories.js +0 -59
- package/stories/PxColorPanel.stories.js +0 -31
- package/stories/PxColorPicker.stories.js +0 -41
- package/stories/PxContain.stories.js +0 -80
- package/stories/PxCopyText.stories.js +0 -35
- package/stories/PxCorners.stories.js +0 -187
- package/stories/PxDatePicker.stories.js +0 -36
- package/stories/PxDropdown.stories.js +0 -56
- package/stories/PxExpander.stories.js +0 -33
- package/stories/PxFit.stories.js +0 -40
- package/stories/PxFlex.stories.js +0 -41
- package/stories/PxFlip.stories.js +0 -51
- package/stories/PxFloat.stories.js +0 -147
- package/stories/PxGsapScrubber.stories.js +0 -36
- package/stories/PxIcon.stories.js +0 -189
- package/stories/PxIconButton.stories.js +0 -87
- package/stories/PxImage.stories.js +0 -113
- package/stories/PxLabeledInput.stories.js +0 -44
- package/stories/PxMeasureContainer.stories.js +0 -50
- package/stories/PxMenu.stories.js +0 -99
- package/stories/PxPivot.stories.js +0 -42
- package/stories/PxPopupButton.stories.js +0 -69
- package/stories/PxProgressCircle.stories.js +0 -39
- package/stories/PxQrCode.stories.js +0 -36
- package/stories/PxRadioButton.stories.js +0 -35
- package/stories/PxResizer.stories.js +0 -40
- package/stories/PxScrubber.stories.js +0 -58
- package/stories/PxSideDrawer.stories.js +0 -36
- package/stories/PxSlides.stories.js +0 -65
- package/stories/PxSpinner.stories.js +0 -37
- package/stories/PxSticky.stories.js +0 -36
- package/stories/PxSvg.stories.js +0 -46
- package/stories/PxSvgRender.stories.js +0 -40
- package/stories/PxSyncHeight.stories.js +0 -48
- package/stories/PxTable.stories.js +0 -145
- package/stories/PxTextbox.stories.js +0 -59
- package/stories/PxToggle.stories.js +0 -77
- package/stories/PxToggleButton.stories.js +0 -109
- package/stories/PxToggleButtonList.stories.js +0 -102
- package/stories/PxToolPanel.stories.js +0 -351
- package/stories/PxTransition.stories.js +0 -74
- package/stories/PxTransitionExpand.stories.js +0 -36
- package/stories/PxTransitionItem.stories.js +0 -36
- package/stories/PxValidator.stories.js +0 -100
- package/stories/assets/alpha.svg +0 -6
- package/stories/assets/alphaNoSizing.svg +0 -6
- package/stories/assets/alphaSizeWidth.svg +0 -6
- package/stories/assets/px-01.jpg +0 -0
- package/stories/assets/px-02.jpg +0 -0
- package/stories/assets/px-03.jpg +0 -0
- package/stories/assets/px-04.jpg +0 -0
- package/stories/makestories.js +0 -65
- package/stories/svgIcon.stories.js +0 -67
- package/storybook/sb-sampledata.js +0 -664
- package/storybook/sb-styles.scss +0 -200
- package/storybook/sb-utils.js +0 -30
- package/test/MockComponent.vue +0 -12
- package/test/PxBaseColor.test.js +0 -54
- package/test/PxBaseItems.test.js +0 -95
- package/test/PxBaseItemsSelect.test.js +0 -470
- package/test/PxBaseUniqueId.test.js +0 -29
- package/test/PxBaseVariants.test.js +0 -166
- package/test/PxBaseVariantsOverride.test.js +0 -87
- package/test/animation.test.js +0 -120
- package/test/cssStr.test.js +0 -287
- package/test/utils.test.js +0 -60
- package/test/variants.test.js +0 -92
- package/vite.config.js +0 -37
- package/vue.config.js +0 -12
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Storybook
|
|
4
4
|
|
|
5
|
-
Basic component preview and testing can be done with storybook. Run storybook with `
|
|
5
|
+
Basic component preview and testing can be done with storybook. Run storybook with `pnpm storybook-px`.
|
|
6
6
|
|
|
7
7
|
## Migration Notes / Approach
|
|
8
8
|
|
|
@@ -73,8 +73,8 @@ watch: {
|
|
|
73
73
|
|
|
74
74
|
## Styles / Customization
|
|
75
75
|
|
|
76
|
-
-
|
|
77
|
-
-
|
|
76
|
+
- **Component Fallbacks** Hardcoded values defined in the component style.
|
|
77
|
+
- **Component Variants** Overrides defined within the component
|
|
78
78
|
|
|
79
79
|
App Defaults App Scoped Defaults App Variants
|
|
80
80
|
|
|
@@ -162,29 +162,24 @@ See [Vite Configuration Reference](https://vitejs.dev/config/).
|
|
|
162
162
|
### Project Setup
|
|
163
163
|
|
|
164
164
|
```sh
|
|
165
|
-
|
|
165
|
+
pnpm install
|
|
166
166
|
```
|
|
167
167
|
|
|
168
|
-
####
|
|
168
|
+
#### Component preview & development with [Storybook](https://storybook.js.org/)
|
|
169
169
|
|
|
170
170
|
```sh
|
|
171
|
-
|
|
172
|
-
```
|
|
173
|
-
|
|
174
|
-
#### Compile and Minify for Production
|
|
175
|
-
|
|
176
|
-
```sh
|
|
177
|
-
npm run build
|
|
171
|
+
pnpm storybook
|
|
178
172
|
```
|
|
179
173
|
|
|
180
174
|
#### Run Unit Tests with [Vitest](https://vitest.dev/)
|
|
181
175
|
|
|
182
176
|
```sh
|
|
183
|
-
|
|
177
|
+
pnpm test
|
|
184
178
|
```
|
|
185
179
|
|
|
186
|
-
####
|
|
180
|
+
#### Format with [oxfmt](https://oxc.rs/docs/guide/usage/formatter.html) and lint with [oxlint](https://oxc.rs/docs/guide/usage/linter.html)
|
|
187
181
|
|
|
188
182
|
```sh
|
|
189
|
-
|
|
183
|
+
pnpm format
|
|
184
|
+
pnpm lint
|
|
190
185
|
```
|
package/bases/PxBaseScroll.vue
CHANGED
|
@@ -169,7 +169,8 @@ export default {
|
|
|
169
169
|
width: 100%;
|
|
170
170
|
border-radius: var(--px-color-panel-radius);
|
|
171
171
|
|
|
172
|
-
background-image:
|
|
172
|
+
background-image:
|
|
173
|
+
linear-gradient(rgba(0, 0, 0, 0), #000),
|
|
173
174
|
linear-gradient(90deg, #fff, var(--px-color-panel-hsl-hue));
|
|
174
175
|
}
|
|
175
176
|
|
package/composables/loadGsap.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Lazy loading utilities for GSAP and ScrollTrigger
|
|
5
|
-
*
|
|
5
|
+
*
|
|
6
6
|
* These functions provide race-condition-safe loading of GSAP libraries.
|
|
7
7
|
* They ensure single initialization even with concurrent calls.
|
|
8
8
|
*/
|
|
@@ -12,13 +12,13 @@ let scrollTriggerPromise = null;
|
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Loads the GSAP library lazily
|
|
15
|
-
*
|
|
15
|
+
*
|
|
16
16
|
* @returns {Promise} Promise that resolves to the GSAP instance
|
|
17
|
-
*
|
|
17
|
+
*
|
|
18
18
|
* @example
|
|
19
19
|
* // Direct usage (not recommended - use useGsap composable instead)
|
|
20
20
|
* import { loadGsap } from '@thinkpixellab-public/px-vue/composables/loadGsap';
|
|
21
|
-
*
|
|
21
|
+
*
|
|
22
22
|
* const gsap = await loadGsap();
|
|
23
23
|
* gsap.to('.element', { x: 100 });
|
|
24
24
|
*/
|
|
@@ -31,15 +31,15 @@ export const loadGsap = async () => {
|
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Loads GSAP with ScrollTrigger plugin registered
|
|
34
|
-
*
|
|
34
|
+
*
|
|
35
35
|
* @returns {Promise} Promise that resolves to { gsap, ScrollTrigger }
|
|
36
|
-
*
|
|
36
|
+
*
|
|
37
37
|
* @example
|
|
38
38
|
* // Direct usage (not recommended - use useScrollAnimation composable instead)
|
|
39
39
|
* import { loadScrollTrigger } from '@thinkpixellab-public/px-vue/composables/loadGsap';
|
|
40
|
-
*
|
|
40
|
+
*
|
|
41
41
|
* const { gsap, ScrollTrigger } = await loadScrollTrigger();
|
|
42
|
-
*
|
|
42
|
+
*
|
|
43
43
|
* gsap.to('.element', {
|
|
44
44
|
* x: 100,
|
|
45
45
|
* scrollTrigger: {
|
|
@@ -52,9 +52,9 @@ export const loadScrollTrigger = async () => {
|
|
|
52
52
|
if (!scrollTriggerPromise) {
|
|
53
53
|
scrollTriggerPromise = (async () => {
|
|
54
54
|
const [gsap, { ScrollTrigger }, { CSSPlugin }] = await Promise.all([
|
|
55
|
-
loadGsap(),
|
|
55
|
+
loadGsap(),
|
|
56
56
|
import('gsap/ScrollTrigger'),
|
|
57
|
-
import('gsap/CSSPlugin')
|
|
57
|
+
import('gsap/CSSPlugin'),
|
|
58
58
|
]);
|
|
59
59
|
gsap.registerPlugin(ScrollTrigger, CSSPlugin);
|
|
60
60
|
return { gsap, ScrollTrigger };
|
package/package.json
CHANGED
|
@@ -1,12 +1,29 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thinkpixellab-public/px-vue",
|
|
3
|
-
"version": "5.0
|
|
3
|
+
"version": "5.2.0",
|
|
4
4
|
"description": "General purpose Vue components and helpers that can be used across projects.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Pixel Lab"
|
|
7
7
|
},
|
|
8
8
|
"license": "MIT",
|
|
9
9
|
"type": "module",
|
|
10
|
+
"engines": {
|
|
11
|
+
"node": ">=24 <25"
|
|
12
|
+
},
|
|
13
|
+
"packageManager": "pnpm@11.5.2",
|
|
14
|
+
"publishConfig": {
|
|
15
|
+
"access": "public"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"assets",
|
|
19
|
+
"bases",
|
|
20
|
+
"components",
|
|
21
|
+
"composables",
|
|
22
|
+
"plugins",
|
|
23
|
+
"styles",
|
|
24
|
+
"utils",
|
|
25
|
+
"nuxt-module.js"
|
|
26
|
+
],
|
|
10
27
|
"repository": {
|
|
11
28
|
"type": "git",
|
|
12
29
|
"url": "git+https://github.com/thinkpixellab/px-vue.git"
|
|
@@ -16,62 +33,63 @@
|
|
|
16
33
|
"storybook": "storybook dev -p 6006",
|
|
17
34
|
"build-storybook": "storybook build",
|
|
18
35
|
"test": "vitest",
|
|
19
|
-
"
|
|
20
|
-
"chromatic": "npx chromatic --project-token=chpt_30d6cbeac803e5a"
|
|
36
|
+
"test:run": "vitest run",
|
|
37
|
+
"chromatic": "npx chromatic --project-token=chpt_30d6cbeac803e5a",
|
|
38
|
+
"format": "oxfmt --write .",
|
|
39
|
+
"format:check": "oxfmt --check .",
|
|
40
|
+
"lint": "oxlint",
|
|
41
|
+
"lint:fix": "oxlint --fix",
|
|
42
|
+
"prepare": "git config core.hooksPath .githooks || true"
|
|
21
43
|
},
|
|
22
44
|
"dependencies": {
|
|
23
|
-
"@floating-ui/dom": "^1.6
|
|
45
|
+
"@floating-ui/dom": "^1.7.6",
|
|
24
46
|
"@popperjs/core": "^2.11.8",
|
|
25
|
-
"@thinkpixellab-public/px-styles": "^4.1
|
|
47
|
+
"@thinkpixellab-public/px-styles": "^4.2.1",
|
|
26
48
|
"@thinkpixellab-public/px-vue-tester": "^2.0.0",
|
|
27
|
-
"@thinkpixellab-public/vue-resize-directive": "^1.2.2",
|
|
28
49
|
"body-scroll-lock": "^3.1.5",
|
|
29
|
-
"chrono-node": "^2.
|
|
50
|
+
"chrono-node": "^2.9.1",
|
|
30
51
|
"dateformat": "^5.0.3",
|
|
31
52
|
"figma-squircle": "^1.1.0",
|
|
32
|
-
"gsap": "^3.
|
|
53
|
+
"gsap": "^3.15.0",
|
|
33
54
|
"highlight.js": "^11.11.1",
|
|
34
|
-
"lenis": "^1.
|
|
55
|
+
"lenis": "^1.3.23",
|
|
35
56
|
"mitt": "^3.0.1",
|
|
36
57
|
"qr-code-styling": "^1.9.2",
|
|
37
|
-
"sortablejs": "^1.15.
|
|
58
|
+
"sortablejs": "^1.15.7",
|
|
38
59
|
"throttle-debounce": "^5.0.2",
|
|
39
60
|
"tiny-date-picker": "^3.2.8",
|
|
40
61
|
"tinycolor2": "^1.6.0",
|
|
41
|
-
"vue-inline-svg": "^
|
|
62
|
+
"vue-inline-svg": "^4.0.1"
|
|
42
63
|
},
|
|
43
64
|
"devDependencies": {
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"@storybook/
|
|
49
|
-
"@storybook/
|
|
50
|
-
"@
|
|
51
|
-
"@
|
|
52
|
-
"@storybook
|
|
53
|
-
"
|
|
54
|
-
"
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
"vite": "^6.2.2",
|
|
73
|
-
"vitest": "^3.0.9",
|
|
74
|
-
"vue-loader": "^17.4.2"
|
|
65
|
+
"@chromatic-com/storybook": "^5.2.1",
|
|
66
|
+
"@nuxt/kit": "^4.4.7",
|
|
67
|
+
"@storybook/addon-docs": "^10.4.2",
|
|
68
|
+
"@storybook/addon-links": "^10.4.2",
|
|
69
|
+
"@storybook/vue3": "^10.4.2",
|
|
70
|
+
"@storybook/vue3-vite": "^10.4.2",
|
|
71
|
+
"@vitejs/plugin-vue": "^6.0.7",
|
|
72
|
+
"@vue/test-utils": "^2.4.11",
|
|
73
|
+
"@vueless/storybook-dark-mode": "^10.0.8",
|
|
74
|
+
"chromatic": "^17.2.0",
|
|
75
|
+
"jsdom": "^29.1.1",
|
|
76
|
+
"oxfmt": "^0.53.0",
|
|
77
|
+
"oxlint": "^1.68.0",
|
|
78
|
+
"sass": "^1.100.0",
|
|
79
|
+
"storybook": "^10.4.2",
|
|
80
|
+
"storybook-addon-pseudo-states": "^10.4.2",
|
|
81
|
+
"vite": "^8.0.16",
|
|
82
|
+
"vitest": "^4.1.8",
|
|
83
|
+
"vue": "^3.5.35"
|
|
84
|
+
},
|
|
85
|
+
"peerDependencies": {
|
|
86
|
+
"@nuxt/kit": "^3.0.0 || ^4.0.0",
|
|
87
|
+
"vue": "^3.2.25"
|
|
88
|
+
},
|
|
89
|
+
"peerDependenciesMeta": {
|
|
90
|
+
"@nuxt/kit": {
|
|
91
|
+
"optional": true
|
|
92
|
+
}
|
|
75
93
|
},
|
|
76
94
|
"bugs": {
|
|
77
95
|
"url": "https://github.com/thinkpixellab/px-vue/issues"
|
package/plugins/common-client.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import mitt from 'mitt';
|
|
2
|
-
import resize from '@thinkpixellab-public/vue-resize-directive';
|
|
3
2
|
|
|
4
3
|
export default {
|
|
5
4
|
install: app => {
|
|
@@ -18,7 +17,5 @@ export default {
|
|
|
18
17
|
app.config.globalProperties.$globalOff = function (eventName, fn) {
|
|
19
18
|
$eventBus.off(eventName, fn);
|
|
20
19
|
};
|
|
21
|
-
|
|
22
|
-
app.directive('resize', resize);
|
|
23
20
|
},
|
|
24
21
|
};
|
package/plugins/common.js
CHANGED
|
@@ -56,9 +56,6 @@ export default {
|
|
|
56
56
|
// $eventBus is only client-side but we want to avoid warnings about missing $eventBus
|
|
57
57
|
// for inject called during setup on server-side.
|
|
58
58
|
app.provide('$eventBus', null);
|
|
59
|
-
|
|
60
|
-
// v-resize is only client-side but we want to avoid warnings about missing directive
|
|
61
|
-
app.directive('resize', {});
|
|
62
59
|
}
|
|
63
60
|
},
|
|
64
61
|
};
|
|
@@ -88,11 +88,11 @@ class HeightGroup {
|
|
|
88
88
|
console.log(`ignore: ${ignore}`);
|
|
89
89
|
console.log(
|
|
90
90
|
'valid heights:',
|
|
91
|
-
heights.filter(height => height <= ignore)
|
|
91
|
+
heights.filter(height => height <= ignore),
|
|
92
92
|
);
|
|
93
93
|
console.log(
|
|
94
94
|
'invalid heights:',
|
|
95
|
-
heights.filter(height => height > ignore)
|
|
95
|
+
heights.filter(height => height > ignore),
|
|
96
96
|
);
|
|
97
97
|
}
|
|
98
98
|
}, this.ops.debounce);
|
|
@@ -526,7 +526,7 @@ const reverseTemplate = template => {
|
|
|
526
526
|
const mergeH = (a, b) => {
|
|
527
527
|
if (!a || !a.length || !b || b.length || a.length !== b.length) {
|
|
528
528
|
console.warn(
|
|
529
|
-
'Cannot horizontally merge empty templates or templates of different lengths.'
|
|
529
|
+
'Cannot horizontally merge empty templates or templates of different lengths.',
|
|
530
530
|
);
|
|
531
531
|
return [];
|
|
532
532
|
}
|
package/utils/scrollWatcher.js
CHANGED
|
@@ -109,19 +109,19 @@ class ScrollWatcherElement {
|
|
|
109
109
|
// If element is smaller than viewport...
|
|
110
110
|
// overlapping begins when the bottom of the element meets the bottom of the viewport
|
|
111
111
|
this.calc.progressBegin = Math.round(
|
|
112
|
-
this.calc.elementRect.bottom - this.calc.viewport.bottom
|
|
112
|
+
this.calc.elementRect.bottom - this.calc.viewport.bottom,
|
|
113
113
|
);
|
|
114
114
|
this.calc.progressDuration = Math.round(
|
|
115
|
-
this.calc.viewport.height - this.calc.elementRect.height
|
|
115
|
+
this.calc.viewport.height - this.calc.elementRect.height,
|
|
116
116
|
);
|
|
117
117
|
} else {
|
|
118
118
|
// If element is larger than viewport...
|
|
119
119
|
// begin when the top of the element is at the top of the viewport
|
|
120
120
|
this.calc.progressBegin = Math.round(
|
|
121
|
-
this.calc.elementRect.top - this.calc.viewport.top
|
|
121
|
+
this.calc.elementRect.top - this.calc.viewport.top,
|
|
122
122
|
);
|
|
123
123
|
this.calc.progressDuration = Math.round(
|
|
124
|
-
this.calc.elementRect.height - this.calc.viewport.height
|
|
124
|
+
this.calc.elementRect.height - this.calc.viewport.height,
|
|
125
125
|
);
|
|
126
126
|
}
|
|
127
127
|
} else {
|
|
@@ -129,10 +129,10 @@ class ScrollWatcherElement {
|
|
|
129
129
|
// Occurs as any part of the element is within any part of the viewport
|
|
130
130
|
|
|
131
131
|
this.calc.progressBegin = Math.round(
|
|
132
|
-
this.calc.elementRect.top - this.calc.viewport.bottom
|
|
132
|
+
this.calc.elementRect.top - this.calc.viewport.bottom,
|
|
133
133
|
);
|
|
134
134
|
this.calc.progressDuration = Math.round(
|
|
135
|
-
this.calc.viewport.height + this.calc.elementRect.height
|
|
135
|
+
this.calc.viewport.height + this.calc.elementRect.height,
|
|
136
136
|
);
|
|
137
137
|
}
|
|
138
138
|
|
package/utils/smootherCorners.js
CHANGED
|
@@ -175,16 +175,14 @@ export function getSmoothCornersPath(options = {}) {
|
|
|
175
175
|
|
|
176
176
|
// calculate corner radii with percentage support and clamping
|
|
177
177
|
const radii = calculateCornerRadii(radius, adjustedWidth, adjustedHeight, minRadius, maxRadius);
|
|
178
|
-
|
|
178
|
+
|
|
179
179
|
// check if all radii are 0 - no need for clipping/masking
|
|
180
180
|
if (radii.every(r => r === 0)) {
|
|
181
181
|
return null;
|
|
182
182
|
}
|
|
183
|
-
|
|
183
|
+
|
|
184
184
|
// adjust radii for inner path when borderWidth is present
|
|
185
|
-
const adjustedRadii = borderWidth > 0
|
|
186
|
-
? radii.map(r => Math.max(0, r - borderWidth))
|
|
187
|
-
: radii;
|
|
185
|
+
const adjustedRadii = borderWidth > 0 ? radii.map(r => Math.max(0, r - borderWidth)) : radii;
|
|
188
186
|
|
|
189
187
|
const path = generateSquirclePath(
|
|
190
188
|
adjustedWidth,
|
|
@@ -214,13 +212,13 @@ export function getSmoothCornersPath(options = {}) {
|
|
|
214
212
|
*/
|
|
215
213
|
export function getBorderMaskStyles(options = {}) {
|
|
216
214
|
const { width, height, borderWidth = 0 } = options;
|
|
217
|
-
|
|
215
|
+
|
|
218
216
|
if (width <= 0 || height <= 0 || borderWidth <= 0) return null;
|
|
219
|
-
|
|
217
|
+
|
|
220
218
|
// Create the inner path (smaller for content area)
|
|
221
219
|
const innerPath = getSmoothCornersPath({
|
|
222
|
-
width: width -
|
|
223
|
-
height: height -
|
|
220
|
+
width: width - borderWidth * 2,
|
|
221
|
+
height: height - borderWidth * 2,
|
|
224
222
|
radius: options.radius,
|
|
225
223
|
smoothing: options.smoothing,
|
|
226
224
|
borderWidth: 0,
|
|
@@ -228,13 +226,13 @@ export function getBorderMaskStyles(options = {}) {
|
|
|
228
226
|
maxRadius: options.maxRadius,
|
|
229
227
|
preserveSmoothing: options.preserveSmoothing,
|
|
230
228
|
});
|
|
231
|
-
|
|
229
|
+
|
|
232
230
|
if (!innerPath) return null;
|
|
233
|
-
|
|
231
|
+
|
|
234
232
|
// Position the inner mask to create border space
|
|
235
233
|
const maskPosition = `${borderWidth}px ${borderWidth}px`;
|
|
236
|
-
const maskSize = `${width -
|
|
237
|
-
|
|
234
|
+
const maskSize = `${width - borderWidth * 2}px ${height - borderWidth * 2}px`;
|
|
235
|
+
|
|
238
236
|
return {
|
|
239
237
|
WebkitMask: `radial-gradient(white, white), ${innerPath}`,
|
|
240
238
|
mask: `radial-gradient(white, white), ${innerPath}`,
|
|
@@ -245,7 +243,7 @@ export function getBorderMaskStyles(options = {}) {
|
|
|
245
243
|
WebkitMaskSize: `100% 100%, ${maskSize}`,
|
|
246
244
|
maskSize: `100% 100%, ${maskSize}`,
|
|
247
245
|
WebkitMaskRepeat: 'no-repeat, no-repeat',
|
|
248
|
-
maskRepeat: 'no-repeat, no-repeat'
|
|
246
|
+
maskRepeat: 'no-repeat, no-repeat',
|
|
249
247
|
};
|
|
250
248
|
}
|
|
251
249
|
|
|
@@ -257,54 +255,54 @@ export function getBorderMaskStyles(options = {}) {
|
|
|
257
255
|
*/
|
|
258
256
|
export function getBorderMaskClipPath(options = {}) {
|
|
259
257
|
const { width, height, borderWidth = 0, renderMode = 'clip-path' } = options;
|
|
260
|
-
|
|
258
|
+
|
|
261
259
|
if (width <= 0 || height <= 0 || borderWidth <= 0) return null;
|
|
262
|
-
|
|
260
|
+
|
|
263
261
|
// Check if the border is too large for the element
|
|
264
262
|
if (borderWidth * 2 >= width || borderWidth * 2 >= height) return null;
|
|
265
|
-
|
|
263
|
+
|
|
266
264
|
// Create outer rectangle path (clockwise)
|
|
267
265
|
const rectPath = `M 0 0 H ${width} V ${height} H 0 Z`;
|
|
268
|
-
|
|
266
|
+
|
|
269
267
|
// Generate the inner smooth path directly at the correct size and position
|
|
270
|
-
const innerWidth = width -
|
|
271
|
-
const innerHeight = height -
|
|
272
|
-
|
|
268
|
+
const innerWidth = width - borderWidth * 2;
|
|
269
|
+
const innerHeight = height - borderWidth * 2;
|
|
270
|
+
|
|
273
271
|
// Calculate radii for the outer dimensions first
|
|
274
272
|
const outerRadii = calculateCornerRadii(
|
|
275
273
|
options.radius,
|
|
276
274
|
width,
|
|
277
275
|
height,
|
|
278
276
|
options.minRadius || 0,
|
|
279
|
-
options.maxRadius || Infinity
|
|
277
|
+
options.maxRadius || Infinity,
|
|
280
278
|
);
|
|
281
|
-
|
|
279
|
+
|
|
282
280
|
// check if all radii are 0 - no need for border masking
|
|
283
281
|
if (outerRadii.every(r => r === 0)) {
|
|
284
282
|
return null;
|
|
285
283
|
}
|
|
286
|
-
|
|
284
|
+
|
|
287
285
|
// Adjust radii for the inner path by subtracting border width
|
|
288
286
|
// This ensures consistent border thickness around corners
|
|
289
287
|
const innerRadii = outerRadii.map(r => Math.max(0, r - borderWidth));
|
|
290
|
-
|
|
288
|
+
|
|
291
289
|
// Generate the inner path with adjusted radii
|
|
292
290
|
const innerSmoothPath = generateSquirclePath(
|
|
293
291
|
innerWidth,
|
|
294
292
|
innerHeight,
|
|
295
293
|
innerRadii,
|
|
296
294
|
options.smoothing || 0.8,
|
|
297
|
-
options.preserveSmoothing !== false
|
|
295
|
+
options.preserveSmoothing !== false,
|
|
298
296
|
);
|
|
299
|
-
|
|
297
|
+
|
|
300
298
|
if (!innerSmoothPath) return null;
|
|
301
|
-
|
|
299
|
+
|
|
302
300
|
// Apply offset to position the inner path
|
|
303
301
|
const offsetInnerPath = applyPathOffset(innerSmoothPath, borderWidth, borderWidth);
|
|
304
|
-
|
|
302
|
+
|
|
305
303
|
// Combine the paths
|
|
306
304
|
const combinedPath = `${rectPath} ${offsetInnerPath}`;
|
|
307
|
-
|
|
305
|
+
|
|
308
306
|
// Return format based on render mode
|
|
309
307
|
if (renderMode === 'mask') {
|
|
310
308
|
return createSvgBorderMaskDataUrl(combinedPath, width, height);
|
|
@@ -313,7 +311,6 @@ export function getBorderMaskClipPath(options = {}) {
|
|
|
313
311
|
}
|
|
314
312
|
}
|
|
315
313
|
|
|
316
|
-
|
|
317
314
|
/**
|
|
318
315
|
* Create SVG mask data URL from path string
|
|
319
316
|
* @param {string} pathString - SVG path string
|
|
@@ -331,14 +328,14 @@ export function createSvgMaskDataUrl(pathString, width, height) {
|
|
|
331
328
|
</defs>
|
|
332
329
|
<rect width="100%" height="100%" fill="white" mask="url(#smooth-mask)"/>
|
|
333
330
|
</svg>`;
|
|
334
|
-
|
|
331
|
+
|
|
335
332
|
return `url('data:image/svg+xml;utf8,${encodeURIComponent(svgContent)}')`;
|
|
336
333
|
}
|
|
337
334
|
|
|
338
335
|
/**
|
|
339
336
|
* Create SVG border mask data URL using compound path approach
|
|
340
337
|
* @param {string} compoundPathString - Compound path string (outer rect + inner hole)
|
|
341
|
-
* @param {number} width - Mask width
|
|
338
|
+
* @param {number} width - Mask width
|
|
342
339
|
* @param {number} height - Mask height
|
|
343
340
|
* @returns {string} Data URL for SVG border mask
|
|
344
341
|
*/
|
|
@@ -351,7 +348,7 @@ export function createSvgBorderMaskDataUrl(compoundPathString, width, height) {
|
|
|
351
348
|
</defs>
|
|
352
349
|
<rect width="100%" height="100%" fill="white" mask="url(#border-mask)"/>
|
|
353
350
|
</svg>`;
|
|
354
|
-
|
|
351
|
+
|
|
355
352
|
return `url('data:image/svg+xml;utf8,${encodeURIComponent(svgContent)}')`;
|
|
356
353
|
}
|
|
357
354
|
|
|
@@ -376,11 +373,9 @@ export function generateSmoothCornersConfig(options = {}) {
|
|
|
376
373
|
const adjustedHeight = Math.max(0, height - borderWidth * 2);
|
|
377
374
|
|
|
378
375
|
const radii = calculateCornerRadii(radius, adjustedWidth, adjustedHeight, minRadius, maxRadius);
|
|
379
|
-
|
|
376
|
+
|
|
380
377
|
// adjust radii for inner path when borderWidth is present
|
|
381
|
-
const adjustedRadii = borderWidth > 0
|
|
382
|
-
? radii.map(r => Math.max(0, r - borderWidth))
|
|
383
|
-
: radii;
|
|
378
|
+
const adjustedRadii = borderWidth > 0 ? radii.map(r => Math.max(0, r - borderWidth)) : radii;
|
|
384
379
|
|
|
385
380
|
return {
|
|
386
381
|
width: adjustedWidth,
|
package/.eslintrc.js
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
module.exports = {
|
|
2
|
-
root: true,
|
|
3
|
-
env: {
|
|
4
|
-
node: true,
|
|
5
|
-
},
|
|
6
|
-
extends: ['plugin:vue/essential', 'eslint:recommended', '@vue/prettier'],
|
|
7
|
-
parserOptions: {
|
|
8
|
-
parser: 'babel-eslint',
|
|
9
|
-
},
|
|
10
|
-
rules: {
|
|
11
|
-
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
|
12
|
-
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
|
13
|
-
},
|
|
14
|
-
};
|
package/.prettierrc.json
DELETED
package/.storybook/main.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/** @type { import('@storybook/vue3-vite').StorybookConfig } */
|
|
2
|
-
const config = {
|
|
3
|
-
stories: ['../stories/**/*.mdx', '../stories/**/*.stories.@(js|jsx|ts|tsx)'],
|
|
4
|
-
addons: [
|
|
5
|
-
'@storybook/addon-links',
|
|
6
|
-
'@storybook/addon-essentials',
|
|
7
|
-
'@storybook/addon-interactions',
|
|
8
|
-
'@chromatic-com/storybook',
|
|
9
|
-
'storybook-addon-pseudo-states',
|
|
10
|
-
'storybook-dark-mode',
|
|
11
|
-
],
|
|
12
|
-
|
|
13
|
-
framework: {
|
|
14
|
-
name: '@storybook/vue3-vite',
|
|
15
|
-
options: {},
|
|
16
|
-
},
|
|
17
|
-
|
|
18
|
-
docs: {
|
|
19
|
-
defaultName: 'Documentation'
|
|
20
|
-
},
|
|
21
|
-
|
|
22
|
-
features: {
|
|
23
|
-
interactionsDebugger: true,
|
|
24
|
-
},
|
|
25
|
-
};
|
|
26
|
-
export default config;
|
|
File without changes
|
package/.storybook/manager.js
DELETED
package/.storybook/preview.js
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { setup } from '@storybook/vue3';
|
|
2
|
-
import common from '../plugins/common.js';
|
|
3
|
-
import './preview.scss';
|
|
4
|
-
|
|
5
|
-
// px-vue common plugins
|
|
6
|
-
setup(app => {
|
|
7
|
-
app.use(common);
|
|
8
|
-
});
|
|
9
|
-
|
|
10
|
-
const preview = {
|
|
11
|
-
parameters: {
|
|
12
|
-
controls: {
|
|
13
|
-
matchers: {
|
|
14
|
-
color: /(background|color)$/i,
|
|
15
|
-
date: /Date$/,
|
|
16
|
-
string: /(itemsKey|itemsDisabled)$/i,
|
|
17
|
-
},
|
|
18
|
-
},
|
|
19
|
-
order: ['Intro', 'Components'],
|
|
20
|
-
storySort: (a, b) => a.id === b.id ? 0 : a.id.localeCompare(b.id, undefined, { numeric: true }),
|
|
21
|
-
docs: { },
|
|
22
|
-
},
|
|
23
|
-
tags: ['autodocs']
|
|
24
|
-
};
|
|
25
|
-
|
|
26
|
-
export default preview;
|
package/.storybook/preview.scss
DELETED