apptify 0.5.1 → 0.6.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 +19 -66
- package/dist/apptify.css +1 -1
- package/dist/apptify.js +2298 -2140
- package/dist/components/AppleCard.vue.d.ts +76 -0
- package/dist/components/button.d.ts +3 -3
- package/dist/components/content.d.ts +0 -90
- package/dist/components/foundation.d.ts +201 -129
- package/dist/components/link.d.ts +31 -0
- package/dist/components/overlays.d.ts +8 -2
- package/dist/core/context.d.ts +11 -0
- package/dist/core/overlay-surface.d.ts +6 -0
- package/dist/core/popup-motion.d.ts +5 -5
- package/dist/core/popup-placement.d.ts +3 -2
- package/dist/index.d.ts +144 -79
- package/docs/COMPONENTS.md +23 -9
- package/docs/INPUT-WORKSHOP.md +59 -0
- package/docs/PLAYGROUND-TEMPLATE.md +9 -9
- package/package.json +5 -1
- package/templates/playground/README.md +4 -4
- package/templates/playground/index.html +1 -1
- package/templates/playground/package.json +6 -2
- package/templates/playground/source-snapshot.json +138 -53
- package/templates/playground/{playground → src}/App.vue +5 -4
- package/templates/playground/{playground → src}/ComponentDemo.vue +9 -10
- package/templates/playground/{playground → src}/catalog.ts +3 -4
- package/templates/playground/src/components/ComponentIndex.vue +43 -0
- package/templates/playground/src/components/DirectoryDialog.vue +20 -0
- package/templates/playground/src/components/PageFooter.vue +7 -0
- package/templates/playground/{playground → src}/components/UserMenu.vue +11 -11
- package/templates/playground/src/editor/AppleInputExample.vue +78 -0
- package/templates/playground/src/editor/AppleInputPreview.vue +82 -0
- package/templates/playground/src/editor/ComponentDocumentLink.vue +19 -0
- package/templates/playground/src/editor/ComponentWorkshop.vue +81 -0
- package/templates/playground/src/editor/ConfigurableEditor.vue +35 -0
- package/templates/playground/src/editor/LiveVueEditor.vue +133 -0
- package/templates/playground/src/editor/apple-input-source.ts +2 -0
- package/templates/playground/src/editor/apple-input.ts +48 -0
- package/templates/playground/src/editor/contract.ts +14 -0
- package/templates/playground/src/editor/documents.ts +20 -0
- package/templates/playground/src/editor/input-playground.ts +59 -0
- package/templates/playground/src/editor/runtime.ts +5 -0
- package/templates/playground/src/editor/sections.ts +10 -0
- package/templates/playground/{playground → src}/style.css +40 -39
- package/templates/playground/{playground → src}/views/[...all].vue +2 -2
- package/templates/playground/src/views/component-docs/[component].vue +162 -0
- package/templates/playground/src/views/components.vue +148 -0
- package/templates/playground/src/views/index.vue +73 -0
- package/templates/playground/src/views/settings.vue +224 -0
- package/templates/playground/tooling/playground-editor.mjs +114 -0
- package/templates/playground/tooling/prepare-input-source.mjs +38 -0
- package/templates/playground/tsconfig.json +2 -2
- package/templates/playground/vite.config.ts +3 -1
- package/tooling/playground-editor.mjs +114 -0
- package/tooling/prepare-input-source.mjs +38 -0
- package/tooling/prepare-playground.mjs +27 -14
- package/tooling/test-create-apptify.mjs +15 -5
- package/tooling/test-playground-package.mjs +25 -11
- package/templates/playground/playground/components/ComponentIndex.vue +0 -62
- package/templates/playground/playground/components/PageFooter.vue +0 -3
- package/templates/playground/playground/views/components.vue +0 -126
- package/templates/playground/playground/views/index.vue +0 -75
- package/templates/playground/playground/views/settings.vue +0 -98
- /package/templates/playground/{playground → src}/components/not-found-paper-scene.vue +0 -0
- /package/templates/playground/{playground → src}/components/not-found-paper-story.ts +0 -0
- /package/templates/playground/{playground → src}/env.d.ts +0 -0
- /package/templates/playground/{playground → src}/main.ts +0 -0
- /package/templates/playground/{playground → src}/router/index.ts +0 -0
|
@@ -71,6 +71,7 @@ export declare const AppleDialog: import("vue").DefineComponent<import("vue").Ex
|
|
|
71
71
|
disposeLayer: (() => void) | null;
|
|
72
72
|
isTop: boolean;
|
|
73
73
|
depth: number;
|
|
74
|
+
present: boolean;
|
|
74
75
|
}, {
|
|
75
76
|
resolvedMotion(): string;
|
|
76
77
|
}, {
|
|
@@ -217,6 +218,7 @@ export declare const AppleDrawer: import("vue").DefineComponent<import("vue").Ex
|
|
|
217
218
|
disposeLayer: (() => void) | null;
|
|
218
219
|
isTop: boolean;
|
|
219
220
|
depth: number;
|
|
221
|
+
present: boolean;
|
|
220
222
|
}, {
|
|
221
223
|
resolvedMotion(): string;
|
|
222
224
|
}, {
|
|
@@ -363,6 +365,7 @@ export declare const AppleSheet: import("vue").DefineComponent<import("vue").Ext
|
|
|
363
365
|
disposeLayer: (() => void) | null;
|
|
364
366
|
isTop: boolean;
|
|
365
367
|
depth: number;
|
|
368
|
+
present: boolean;
|
|
366
369
|
}, {
|
|
367
370
|
resolvedMotion(): string;
|
|
368
371
|
}, {
|
|
@@ -598,13 +601,13 @@ export declare const ApplePopover: import("vue").DefineComponent<import("vue").E
|
|
|
598
601
|
internalOpen: boolean;
|
|
599
602
|
depth: number;
|
|
600
603
|
isTop: boolean;
|
|
604
|
+
present: boolean;
|
|
601
605
|
disposeLayer: (() => void) | null;
|
|
602
606
|
disposePosition: (() => void) | null;
|
|
603
607
|
hoverTimer: ReturnType<typeof setTimeout> | null;
|
|
604
608
|
positioned: boolean;
|
|
605
609
|
positioner: PopupPositioner | null;
|
|
606
610
|
positionPanel: HTMLElement | null;
|
|
607
|
-
interruptedPopup: number | undefined;
|
|
608
611
|
}, {
|
|
609
612
|
opened(): boolean;
|
|
610
613
|
}, {
|
|
@@ -983,6 +986,7 @@ export declare const overlayComponents: {
|
|
|
983
986
|
disposeLayer: (() => void) | null;
|
|
984
987
|
isTop: boolean;
|
|
985
988
|
depth: number;
|
|
989
|
+
present: boolean;
|
|
986
990
|
}, {
|
|
987
991
|
resolvedMotion(): string;
|
|
988
992
|
}, {
|
|
@@ -1129,6 +1133,7 @@ export declare const overlayComponents: {
|
|
|
1129
1133
|
disposeLayer: (() => void) | null;
|
|
1130
1134
|
isTop: boolean;
|
|
1131
1135
|
depth: number;
|
|
1136
|
+
present: boolean;
|
|
1132
1137
|
}, {
|
|
1133
1138
|
resolvedMotion(): string;
|
|
1134
1139
|
}, {
|
|
@@ -1275,6 +1280,7 @@ export declare const overlayComponents: {
|
|
|
1275
1280
|
disposeLayer: (() => void) | null;
|
|
1276
1281
|
isTop: boolean;
|
|
1277
1282
|
depth: number;
|
|
1283
|
+
present: boolean;
|
|
1278
1284
|
}, {
|
|
1279
1285
|
resolvedMotion(): string;
|
|
1280
1286
|
}, {
|
|
@@ -1510,13 +1516,13 @@ export declare const overlayComponents: {
|
|
|
1510
1516
|
internalOpen: boolean;
|
|
1511
1517
|
depth: number;
|
|
1512
1518
|
isTop: boolean;
|
|
1519
|
+
present: boolean;
|
|
1513
1520
|
disposeLayer: (() => void) | null;
|
|
1514
1521
|
disposePosition: (() => void) | null;
|
|
1515
1522
|
hoverTimer: ReturnType<typeof setTimeout> | null;
|
|
1516
1523
|
positioned: boolean;
|
|
1517
1524
|
positioner: PopupPositioner | null;
|
|
1518
1525
|
positionPanel: HTMLElement | null;
|
|
1519
|
-
interruptedPopup: number | undefined;
|
|
1520
1526
|
}, {
|
|
1521
1527
|
opened(): boolean;
|
|
1522
1528
|
}, {
|
package/dist/core/context.d.ts
CHANGED
|
@@ -316,6 +316,7 @@ export interface AppleOptions {
|
|
|
316
316
|
theme?: string;
|
|
317
317
|
themes?: Record<string, AppleTheme>;
|
|
318
318
|
motion?: Motion;
|
|
319
|
+
ripple?: boolean;
|
|
319
320
|
glass?: Partial<AppleGlassSettings>;
|
|
320
321
|
persist?: boolean;
|
|
321
322
|
storageKey?: string;
|
|
@@ -362,6 +363,16 @@ export declare function createApple(options?: AppleOptions): import("vue").Raw<{
|
|
|
362
363
|
reduced: boolean;
|
|
363
364
|
set: (mode: Motion) => void;
|
|
364
365
|
}>;
|
|
366
|
+
ripple: Ref<{
|
|
367
|
+
enabled: boolean;
|
|
368
|
+
set: (enabled: boolean) => void;
|
|
369
|
+
}, {
|
|
370
|
+
enabled: boolean;
|
|
371
|
+
set(enabled: boolean): void;
|
|
372
|
+
} | {
|
|
373
|
+
enabled: boolean;
|
|
374
|
+
set: (enabled: boolean) => void;
|
|
375
|
+
}>;
|
|
365
376
|
glass: Ref<{
|
|
366
377
|
set: (value: Partial<AppleGlassSettings>) => void;
|
|
367
378
|
reset: () => void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ObjectDirective } from 'vue';
|
|
2
|
+
/** The browser's top layer escapes clipping and transformed containing blocks
|
|
3
|
+
* without moving Vue's DOM, focus scope, or inherited theme out of its owner. */
|
|
4
|
+
export declare function showOverlaySurface(element: HTMLElement): void;
|
|
5
|
+
export declare function hideOverlaySurface(element: HTMLElement): void;
|
|
6
|
+
export declare const OverlaySurface: ObjectDirective<HTMLElement>;
|
|
@@ -2,11 +2,11 @@ import { type VNode, type VNodeChild } from 'vue';
|
|
|
2
2
|
export declare function freezePopup(element: Element): number | undefined;
|
|
3
3
|
export declare function finishPopup(element: HTMLElement): void;
|
|
4
4
|
export declare function resetPopup(element: Element): void;
|
|
5
|
-
export declare function preparePopup(element: Element,
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
export declare function animatePopup(element: Element, opened: boolean, done: () => void
|
|
9
|
-
/** Shared field transition keeps the full panel layout stable during
|
|
5
|
+
export declare function preparePopup(element: Element, interrupted?: number): void;
|
|
6
|
+
/** Animate the complete surface, including its shadow. Keep the current frame
|
|
7
|
+
* until its replacement is ready, including on reversal and placement changes. */
|
|
8
|
+
export declare function animatePopup(element: Element, opened: boolean, done: () => void): void;
|
|
9
|
+
/** Shared field transition keeps the full panel layout stable during motion. */
|
|
10
10
|
export declare function popupTransition(content: VNodeChild, name?: string, persisted?: boolean, gap?: number): VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
11
11
|
[key: string]: any;
|
|
12
12
|
}>;
|
|
@@ -19,9 +19,10 @@ interface PopupPositionOptions {
|
|
|
19
19
|
fixed?: boolean;
|
|
20
20
|
gap?: number;
|
|
21
21
|
}
|
|
22
|
-
/** Keep
|
|
22
|
+
/** Keep measurements in viewport coordinates and never uncap a live scrollport
|
|
23
|
+
* to measure it: doing so clamps scrollTop to zero before constraints return. */
|
|
23
24
|
export declare function createPopupPositioner(panel: HTMLElement, options: PopupPositionOptions): PopupPositioner;
|
|
24
|
-
/**
|
|
25
|
+
/** Field popups retain their DOM/focus owner while rendering in the top layer. */
|
|
25
26
|
export declare function updateFieldPopup(element: HTMLElement): void;
|
|
26
27
|
export declare function unmountFieldPopup(element: HTMLElement): void;
|
|
27
28
|
export declare function mountFieldPopup(element: HTMLElement, gap?: number): void;
|
package/dist/index.d.ts
CHANGED
|
@@ -272,6 +272,7 @@ export declare const components: {
|
|
|
272
272
|
disposeLayer: (() => void) | null;
|
|
273
273
|
isTop: boolean;
|
|
274
274
|
depth: number;
|
|
275
|
+
present: boolean;
|
|
275
276
|
}, {
|
|
276
277
|
resolvedMotion(): string;
|
|
277
278
|
}, {
|
|
@@ -418,6 +419,7 @@ export declare const components: {
|
|
|
418
419
|
disposeLayer: (() => void) | null;
|
|
419
420
|
isTop: boolean;
|
|
420
421
|
depth: number;
|
|
422
|
+
present: boolean;
|
|
421
423
|
}, {
|
|
422
424
|
resolvedMotion(): string;
|
|
423
425
|
}, {
|
|
@@ -564,6 +566,7 @@ export declare const components: {
|
|
|
564
566
|
disposeLayer: (() => void) | null;
|
|
565
567
|
isTop: boolean;
|
|
566
568
|
depth: number;
|
|
569
|
+
present: boolean;
|
|
567
570
|
}, {
|
|
568
571
|
resolvedMotion(): string;
|
|
569
572
|
}, {
|
|
@@ -799,13 +802,13 @@ export declare const components: {
|
|
|
799
802
|
internalOpen: boolean;
|
|
800
803
|
depth: number;
|
|
801
804
|
isTop: boolean;
|
|
805
|
+
present: boolean;
|
|
802
806
|
disposeLayer: (() => void) | null;
|
|
803
807
|
disposePosition: (() => void) | null;
|
|
804
808
|
hoverTimer: ReturnType<typeof setTimeout> | null;
|
|
805
809
|
positioned: boolean;
|
|
806
810
|
positioner: import("./core/popup-placement").PopupPositioner | null;
|
|
807
811
|
positionPanel: HTMLElement | null;
|
|
808
|
-
interruptedPopup: number | undefined;
|
|
809
812
|
}, {
|
|
810
813
|
opened(): boolean;
|
|
811
814
|
}, {
|
|
@@ -2352,51 +2355,6 @@ export declare const components: {
|
|
|
2352
2355
|
threshold: number;
|
|
2353
2356
|
backTop: boolean;
|
|
2354
2357
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2355
|
-
AppleMarquee: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
2356
|
-
text: {
|
|
2357
|
-
type: StringConstructor;
|
|
2358
|
-
default: string;
|
|
2359
|
-
};
|
|
2360
|
-
duration: {
|
|
2361
|
-
type: NumberConstructor;
|
|
2362
|
-
default: number;
|
|
2363
|
-
};
|
|
2364
|
-
paused: BooleanConstructor;
|
|
2365
|
-
label: {
|
|
2366
|
-
type: StringConstructor;
|
|
2367
|
-
default: string;
|
|
2368
|
-
};
|
|
2369
|
-
motion: {
|
|
2370
|
-
type: import("vue").PropType<"auto" | "full" | "reduced" | "none" | "inherit">;
|
|
2371
|
-
default: string;
|
|
2372
|
-
};
|
|
2373
|
-
}>, {}, {
|
|
2374
|
-
userPaused: boolean;
|
|
2375
|
-
}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
2376
|
-
text: {
|
|
2377
|
-
type: StringConstructor;
|
|
2378
|
-
default: string;
|
|
2379
|
-
};
|
|
2380
|
-
duration: {
|
|
2381
|
-
type: NumberConstructor;
|
|
2382
|
-
default: number;
|
|
2383
|
-
};
|
|
2384
|
-
paused: BooleanConstructor;
|
|
2385
|
-
label: {
|
|
2386
|
-
type: StringConstructor;
|
|
2387
|
-
default: string;
|
|
2388
|
-
};
|
|
2389
|
-
motion: {
|
|
2390
|
-
type: import("vue").PropType<"auto" | "full" | "reduced" | "none" | "inherit">;
|
|
2391
|
-
default: string;
|
|
2392
|
-
};
|
|
2393
|
-
}>> & Readonly<{}>, {
|
|
2394
|
-
text: string;
|
|
2395
|
-
duration: number;
|
|
2396
|
-
label: string;
|
|
2397
|
-
motion: "auto" | "full" | "reduced" | "none" | "inherit";
|
|
2398
|
-
paused: boolean;
|
|
2399
|
-
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
2400
2358
|
AppleStatistic: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
2401
2359
|
value: {
|
|
2402
2360
|
type: (NumberConstructor | StringConstructor)[];
|
|
@@ -4105,6 +4063,16 @@ export declare const components: {
|
|
|
4105
4063
|
reduced: boolean;
|
|
4106
4064
|
set: (mode: import(".").Motion) => void;
|
|
4107
4065
|
}>;
|
|
4066
|
+
ripple: import("vue").Ref<{
|
|
4067
|
+
enabled: boolean;
|
|
4068
|
+
set: (enabled: boolean) => void;
|
|
4069
|
+
}, {
|
|
4070
|
+
enabled: boolean;
|
|
4071
|
+
set(enabled: boolean): void;
|
|
4072
|
+
} | {
|
|
4073
|
+
enabled: boolean;
|
|
4074
|
+
set: (enabled: boolean) => void;
|
|
4075
|
+
}>;
|
|
4108
4076
|
glass: import("vue").Ref<{
|
|
4109
4077
|
set: (value: Partial<import(".").AppleGlassSettings>) => void;
|
|
4110
4078
|
reset: () => void;
|
|
@@ -4442,6 +4410,16 @@ export declare const components: {
|
|
|
4442
4410
|
reduced: boolean;
|
|
4443
4411
|
set: (mode: import(".").Motion) => void;
|
|
4444
4412
|
}>;
|
|
4413
|
+
ripple: import("vue").Ref<{
|
|
4414
|
+
enabled: boolean;
|
|
4415
|
+
set: (enabled: boolean) => void;
|
|
4416
|
+
}, {
|
|
4417
|
+
enabled: boolean;
|
|
4418
|
+
set(enabled: boolean): void;
|
|
4419
|
+
} | {
|
|
4420
|
+
enabled: boolean;
|
|
4421
|
+
set: (enabled: boolean) => void;
|
|
4422
|
+
}>;
|
|
4445
4423
|
glass: import("vue").Ref<{
|
|
4446
4424
|
set: (value: Partial<import(".").AppleGlassSettings>) => void;
|
|
4447
4425
|
reset: () => void;
|
|
@@ -4787,6 +4765,16 @@ export declare const components: {
|
|
|
4787
4765
|
reduced: boolean;
|
|
4788
4766
|
set: (mode: import(".").Motion) => void;
|
|
4789
4767
|
}>;
|
|
4768
|
+
ripple: import("vue").Ref<{
|
|
4769
|
+
enabled: boolean;
|
|
4770
|
+
set: (enabled: boolean) => void;
|
|
4771
|
+
}, {
|
|
4772
|
+
enabled: boolean;
|
|
4773
|
+
set(enabled: boolean): void;
|
|
4774
|
+
} | {
|
|
4775
|
+
enabled: boolean;
|
|
4776
|
+
set: (enabled: boolean) => void;
|
|
4777
|
+
}>;
|
|
4790
4778
|
glass: import("vue").Ref<{
|
|
4791
4779
|
set: (value: Partial<import(".").AppleGlassSettings>) => void;
|
|
4792
4780
|
reset: () => void;
|
|
@@ -5086,7 +5074,7 @@ export declare const components: {
|
|
|
5086
5074
|
}, true, {}, any>;
|
|
5087
5075
|
AppleButton: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
5088
5076
|
variant: {
|
|
5089
|
-
type: import("vue").PropType<"primary" | "secondary" | "outline" | "
|
|
5077
|
+
type: import("vue").PropType<"primary" | "secondary" | "outline" | "danger">;
|
|
5090
5078
|
default: string;
|
|
5091
5079
|
};
|
|
5092
5080
|
size: {
|
|
@@ -5113,7 +5101,7 @@ export declare const components: {
|
|
|
5113
5101
|
};
|
|
5114
5102
|
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "click"[], "click", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
5115
5103
|
variant: {
|
|
5116
|
-
type: import("vue").PropType<"primary" | "secondary" | "outline" | "
|
|
5104
|
+
type: import("vue").PropType<"primary" | "secondary" | "outline" | "danger">;
|
|
5117
5105
|
default: string;
|
|
5118
5106
|
};
|
|
5119
5107
|
size: {
|
|
@@ -5145,55 +5133,120 @@ export declare const components: {
|
|
|
5145
5133
|
disabled: boolean;
|
|
5146
5134
|
iconOnly: boolean;
|
|
5147
5135
|
loading: boolean;
|
|
5148
|
-
variant: "secondary" | "danger" | "primary" | "outline"
|
|
5136
|
+
variant: "secondary" | "danger" | "primary" | "outline";
|
|
5149
5137
|
ripple: boolean;
|
|
5150
5138
|
type: "reset" | "submit" | "button";
|
|
5151
5139
|
motion: import(".").ComponentMotion;
|
|
5152
5140
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
5153
5141
|
AppleLink: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
5142
|
+
as: {
|
|
5143
|
+
type: import("vue").PropType<"a" | "button">;
|
|
5144
|
+
default: string;
|
|
5145
|
+
};
|
|
5154
5146
|
href: StringConstructor;
|
|
5155
5147
|
external: BooleanConstructor;
|
|
5156
5148
|
disabled: BooleanConstructor;
|
|
5157
|
-
|
|
5149
|
+
icon: import("vue").PropType<import("vue").Component>;
|
|
5150
|
+
iconOnly: BooleanConstructor;
|
|
5151
|
+
label: StringConstructor;
|
|
5152
|
+
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "click"[], "click", import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
5153
|
+
as: {
|
|
5154
|
+
type: import("vue").PropType<"a" | "button">;
|
|
5155
|
+
default: string;
|
|
5156
|
+
};
|
|
5158
5157
|
href: StringConstructor;
|
|
5159
5158
|
external: BooleanConstructor;
|
|
5160
5159
|
disabled: BooleanConstructor;
|
|
5161
|
-
|
|
5160
|
+
icon: import("vue").PropType<import("vue").Component>;
|
|
5161
|
+
iconOnly: BooleanConstructor;
|
|
5162
|
+
label: StringConstructor;
|
|
5163
|
+
}>> & Readonly<{
|
|
5164
|
+
onClick?: ((...args: any[]) => any) | undefined;
|
|
5165
|
+
}>, {
|
|
5162
5166
|
disabled: boolean;
|
|
5167
|
+
iconOnly: boolean;
|
|
5163
5168
|
external: boolean;
|
|
5169
|
+
as: "a" | "button";
|
|
5164
5170
|
}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
5165
|
-
AppleCard:
|
|
5166
|
-
|
|
5167
|
-
|
|
5168
|
-
|
|
5169
|
-
|
|
5171
|
+
AppleCard: {
|
|
5172
|
+
new (...args: any[]): import("vue").CreateComponentPublicInstanceWithMixins<Readonly<import("vue").ExtractPropTypes<{
|
|
5173
|
+
icon: import("vue").PropType<import("vue").Component | string>;
|
|
5174
|
+
iconColor: StringConstructor;
|
|
5175
|
+
title: StringConstructor;
|
|
5176
|
+
subtitle: StringConstructor;
|
|
5177
|
+
text: StringConstructor;
|
|
5178
|
+
eyebrow: StringConstructor;
|
|
5179
|
+
image: StringConstructor;
|
|
5180
|
+
imageAlt: {
|
|
5181
|
+
type: StringConstructor;
|
|
5182
|
+
default: string;
|
|
5183
|
+
};
|
|
5184
|
+
href: StringConstructor;
|
|
5185
|
+
zoom: {
|
|
5186
|
+
type: import("vue").PropType<"big" | "small" | "none">;
|
|
5187
|
+
default: string;
|
|
5188
|
+
};
|
|
5189
|
+
shadow: {
|
|
5190
|
+
type: import("vue").PropType<"normal" | "static" | "focused" | "none">;
|
|
5191
|
+
default: string;
|
|
5192
|
+
};
|
|
5193
|
+
motion: {
|
|
5194
|
+
type: import("vue").PropType<import(".").ComponentMotion>;
|
|
5195
|
+
default: string;
|
|
5196
|
+
};
|
|
5197
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, import("vue").PublicProps, {
|
|
5198
|
+
shadow: "none" | "static" | "normal" | "focused";
|
|
5199
|
+
motion: import(".").ComponentMotion;
|
|
5200
|
+
zoom: "none" | "big" | "small";
|
|
5201
|
+
imageAlt: string;
|
|
5202
|
+
}, true, {}, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
|
|
5203
|
+
P: {};
|
|
5204
|
+
B: {};
|
|
5205
|
+
D: {};
|
|
5206
|
+
C: {};
|
|
5207
|
+
M: {};
|
|
5208
|
+
Defaults: {};
|
|
5209
|
+
}, Readonly<import("vue").ExtractPropTypes<{
|
|
5210
|
+
icon: import("vue").PropType<import("vue").Component | string>;
|
|
5211
|
+
iconColor: StringConstructor;
|
|
5212
|
+
title: StringConstructor;
|
|
5213
|
+
subtitle: StringConstructor;
|
|
5214
|
+
text: StringConstructor;
|
|
5215
|
+
eyebrow: StringConstructor;
|
|
5216
|
+
image: StringConstructor;
|
|
5217
|
+
imageAlt: {
|
|
5218
|
+
type: StringConstructor;
|
|
5219
|
+
default: string;
|
|
5220
|
+
};
|
|
5221
|
+
href: StringConstructor;
|
|
5222
|
+
zoom: {
|
|
5223
|
+
type: import("vue").PropType<"big" | "small" | "none">;
|
|
5224
|
+
default: string;
|
|
5225
|
+
};
|
|
5226
|
+
shadow: {
|
|
5227
|
+
type: import("vue").PropType<"normal" | "static" | "focused" | "none">;
|
|
5228
|
+
default: string;
|
|
5229
|
+
};
|
|
5230
|
+
motion: {
|
|
5231
|
+
type: import("vue").PropType<import(".").ComponentMotion>;
|
|
5232
|
+
default: string;
|
|
5233
|
+
};
|
|
5234
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, {
|
|
5235
|
+
shadow: "none" | "static" | "normal" | "focused";
|
|
5236
|
+
motion: import(".").ComponentMotion;
|
|
5237
|
+
zoom: "none" | "big" | "small";
|
|
5238
|
+
imageAlt: string;
|
|
5239
|
+
}>;
|
|
5240
|
+
__isFragment?: never;
|
|
5241
|
+
__isTeleport?: never;
|
|
5242
|
+
__isSuspense?: never;
|
|
5243
|
+
} & import("vue").ComponentOptionsBase<Readonly<import("vue").ExtractPropTypes<{
|
|
5170
5244
|
icon: import("vue").PropType<import("vue").Component | string>;
|
|
5171
5245
|
iconColor: StringConstructor;
|
|
5172
|
-
image: StringConstructor;
|
|
5173
|
-
imageAlt: {
|
|
5174
|
-
type: StringConstructor;
|
|
5175
|
-
default: string;
|
|
5176
|
-
};
|
|
5177
|
-
href: StringConstructor;
|
|
5178
|
-
zoom: {
|
|
5179
|
-
type: import("vue").PropType<"big" | "small" | "none">;
|
|
5180
|
-
default: string;
|
|
5181
|
-
};
|
|
5182
|
-
shadow: {
|
|
5183
|
-
type: import("vue").PropType<"normal" | "static" | "focused" | "none">;
|
|
5184
|
-
default: string;
|
|
5185
|
-
};
|
|
5186
|
-
motion: {
|
|
5187
|
-
type: import("vue").PropType<import(".").ComponentMotion>;
|
|
5188
|
-
default: string;
|
|
5189
|
-
};
|
|
5190
|
-
}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
5191
5246
|
title: StringConstructor;
|
|
5192
5247
|
subtitle: StringConstructor;
|
|
5193
5248
|
text: StringConstructor;
|
|
5194
5249
|
eyebrow: StringConstructor;
|
|
5195
|
-
icon: import("vue").PropType<import("vue").Component | string>;
|
|
5196
|
-
iconColor: StringConstructor;
|
|
5197
5250
|
image: StringConstructor;
|
|
5198
5251
|
imageAlt: {
|
|
5199
5252
|
type: StringConstructor;
|
|
@@ -5212,12 +5265,24 @@ export declare const components: {
|
|
|
5212
5265
|
type: import("vue").PropType<import(".").ComponentMotion>;
|
|
5213
5266
|
default: string;
|
|
5214
5267
|
};
|
|
5215
|
-
}>> & Readonly<{}>, {
|
|
5268
|
+
}>> & Readonly<{}>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, {
|
|
5216
5269
|
shadow: "none" | "static" | "normal" | "focused";
|
|
5217
5270
|
motion: import(".").ComponentMotion;
|
|
5218
5271
|
zoom: "none" | "big" | "small";
|
|
5219
5272
|
imageAlt: string;
|
|
5220
|
-
}, {},
|
|
5273
|
+
}, {}, string, {}, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & (new () => {
|
|
5274
|
+
$slots: {
|
|
5275
|
+
media?: (props: {}) => any;
|
|
5276
|
+
} & {
|
|
5277
|
+
icon?: (props: {}) => any;
|
|
5278
|
+
} & {
|
|
5279
|
+
title?: (props: {}) => any;
|
|
5280
|
+
} & {
|
|
5281
|
+
default?: (props: {}) => any;
|
|
5282
|
+
} & {
|
|
5283
|
+
actions?: (props: {}) => any;
|
|
5284
|
+
};
|
|
5285
|
+
});
|
|
5221
5286
|
AppleImage: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
5222
5287
|
preview: {
|
|
5223
5288
|
type: BooleanConstructor;
|
package/docs/COMPONENTS.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
## 公共约定
|
|
6
6
|
|
|
7
|
-
`secondary` 与 `outline`
|
|
7
|
+
`secondary` 与 `outline` 都是描边按钮,纯文字操作使用 `AppleLink`,始终不启用 Ripple。所有 API 可直接从 JavaScript 和普通 Vue `<script>` 使用,TypeScript 不是消费前提。
|
|
8
8
|
|
|
9
9
|
Tabs、TabBar、SegmentedControl、DatePicker 日期/时间页签均不使用 Ripple;保留选中指示器位移与内容切换动画。
|
|
10
10
|
|
|
@@ -15,6 +15,18 @@ Tabs、TabBar、SegmentedControl、DatePicker 日期/时间页签均不使用 Ri
|
|
|
15
15
|
- 内容选项类型为 `AppleItem = { label; value; disabled?; description?; href?; content? }`;`value` 为唯一的 `string | number`。
|
|
16
16
|
- 组件并非 Vuetify 同名组件的透传包装。只依赖这里声明的接口,不假设任意 `v-*` prop、slot 或事件都可直接使用。
|
|
17
17
|
|
|
18
|
+
## Glass 通用样式
|
|
19
|
+
|
|
20
|
+
导入 `apptify/style.css` 后,在 `<apple-provider>` 内给自定义元素添加 `.apple-glass`,即可应用跟随主题和全局 glass 设置的背景、文字颜色与背景模糊:
|
|
21
|
+
|
|
22
|
+
```vue
|
|
23
|
+
<apple-provider>
|
|
24
|
+
<div class="apple-glass">自定义玻璃面板</div>
|
|
25
|
+
</apple-provider>
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
该类只提供材质与文字颜色,间距、圆角、边框和阴影由使用方设置。Provider 外使用默认浅色材质;Provider 内跟随 `glass.opacity` 与 `glass.blur` 配置。
|
|
29
|
+
|
|
18
30
|
## 动效组件 · 2
|
|
19
31
|
|
|
20
32
|
| 组件 | Props | 说明 |
|
|
@@ -24,16 +36,16 @@ Tabs、TabBar、SegmentedControl、DatePicker 日期/时间页签均不使用 Ri
|
|
|
24
36
|
|
|
25
37
|
全局入场使用 `v-apple-entrance="pageKey"` 放在一个页面容器上:首次挂载及 key 改变时整体由下向上 14px,不复制旧页、不执行离场、不改变透明度。不应嵌套应用到同一页面的多层内容。
|
|
26
38
|
|
|
27
|
-
另提供 `v-apple-ripple` 和 `v-apple-selection`;后者移动到后代 `[data-apple-selected="true"]`,也可传 `{selector}
|
|
39
|
+
另提供 `v-apple-ripple` 和 `v-apple-selection`;后者移动到后代 `[data-apple-selected="true"]`,也可传 `{selector}`。selection 遵循全局 none/reduced 与系统减少动态效果限制;ripple 在减弱动效下可手动开启,none 下始终禁用。
|
|
28
40
|
|
|
29
41
|
## 基础组件 · 9
|
|
30
42
|
|
|
31
43
|
| 组件 | 主要 Props | Events / Slots / 说明 |
|
|
32
44
|
| --- | --- | --- |
|
|
33
45
|
| `AppleProvider` | `theme?: string`、`motion?: auto/full/reduced/none` | default slot;应用主题并自动挂载弹层宿主。无显式属性时复用插件上下文。 |
|
|
34
|
-
| `AppleButton` | M;`variant=primary`(primary/secondary/outline/
|
|
35
|
-
| `AppleLink` | `href`、`external`、`disabled` | default slot;external 使用新窗口并设置 `noopener noreferrer`。 |
|
|
36
|
-
| `AppleCard` | M;`title`、`subtitle`、`text`、`eyebrow`、`icon: Component 或图片 URL`、`iconColor`、`image`、`imageAlt`、`href`、`zoom=
|
|
46
|
+
| `AppleButton` | M;`variant=primary`(primary/secondary/outline/danger)、`size=medium`(small/medium/large)、`icon: Component`、`iconOnly`、`label`、`disabled`、`loading`、`ripple=true`、`href`、`type=button` | `click(event)`;default slot;图标位于文字右侧。纯图标按钮须提供 label。关闭动效时禁用 Ripple,其余模式遵循全局波纹开关。 |
|
|
47
|
+
| `AppleLink` | `as=a`(a/button)、`href`、`external`、`disabled`、`icon`、`iconOnly`、`label` | default slot;文字操作使用 as=button;external 使用新窗口并设置 `noopener noreferrer`。 |
|
|
48
|
+
| `AppleCard` | M;`title`、`subtitle`、`text`、`eyebrow`、`icon: Component 或图片 URL`、`iconColor`、`image`、`imageAlt`、`href`、`zoom=none`(big/small/none)、`shadow=normal`(normal/static/focused/none) | default、media、icon、title、actions slots;href 为标题链接,不会把所有嵌套控件变成一个大按钮。 |
|
|
37
49
|
| `AppleImage` | M;`gallery: AppleImageItem | (string/AppleImageItem)[]`(唯一来源,默认空数组,单图可传对象);`preview=true`、`carousel=false`、`disabled=false`、`label`、`galleryLayout=compact`(compact/tiled/tiled-wrap,所有设备)、`galleryShape=natural`(natural/square)、`index=0`、`squared`、`aspectRatio='4/3'`、`fit=cover`(cover/contain) | caption 与 item({item,index,active}) slots;carousel 强制 compact、常显控件且保留自由滚动;默认点击预览;统一入口,按触屏能力选择预览交互;完整渲染图片组,compact 在固定框内横滑,桌面触控板支持自由连续横滑、一次手势可跨越多张,快速点击翻页延续当前位置和速度;hover 不缩放,多图显示左右翻页按钮(单图小窗与全屏均无翻页箭头),跨多张点击小点时直接衔接当前画面与目标图并支持连续改选,tiled 等高横向平铺,溢出时底部常显自定义滚动条,支持拖动、点击轨道与键盘,滑块比例随内容和容器尺寸同步,tiled-wrap 等宽保留图片比例,按列从上往下紧密堆叠,避免按行对齐产生空白;平铺 hover 只缩放当前图片;galleryShape=square 强制 1:1 并居中裁剪(覆盖 fit),squared 同样作用于图片组;`update:index`、`change(index)`;图片错误状态;squared 覆盖 aspectRatio。 |
|
|
38
50
|
| `AppleSearch` | `v-model: string`、`placeholder='搜索'`、`label='搜索'`、`disabled` | `search(value)` 在 Enter 时发出;清空更新 model。 |
|
|
39
51
|
| `AppleContainer` | `width=1200`(number/string) | default slot;数字宽度按 px,宽度不会超过可用空间。 |
|
|
@@ -42,15 +54,17 @@ Tabs、TabBar、SegmentedControl、DatePicker 日期/时间页签均不使用 Ri
|
|
|
42
54
|
|
|
43
55
|
## 表单组件 · 18
|
|
44
56
|
|
|
57
|
+
字段名称、hint、错误提示和行内空白只用于展示,点击不会聚焦、展开或切换控件;直接操作输入框、选择器或开关本身。字段名称通过 ARIA 保留可访问性关联。
|
|
58
|
+
|
|
45
59
|
| 组件 | 主要 Props | Events / Slots / 方法 |
|
|
46
60
|
| --- | --- | --- |
|
|
47
61
|
| `AppleInput` | F;`v-model: string/number`、`type=text`、`placeholder`、`clearable` | `change(value)`、`clear()`;prefix/suffix slots;`focus()`;输入事件实际返回字符串。password 类型带显隐按钮。 |
|
|
48
62
|
| `AppleTextarea` | F;`v-model: string`、`placeholder`、`rows=4`、`maxlength`、`counter`、`resize=true` | `change(value)`;`focus()`;resize=true 允许纵向缩放。 |
|
|
49
63
|
| `AppleSelect` | F;`v-model: string/number/null`、`items: AppleOption[]`、`placeholder='请选择'` | `change(value)`;自绘半透明模糊下拉,支持键盘导航和 required 校验。 |
|
|
50
64
|
| `AppleAutocomplete` | F;`v-model: string/number/null`、`items`、`placeholder`、`emptyText`、`clearable=true`、`filter(query,item)` | `change(value)`、`search(query)`;`focus()`;方向键/Enter/Escape;是单选过滤,不是多选标签输入。 |
|
|
51
|
-
| `AppleCheckbox` | F;`v-model: boolean`、`indeterminate` | `change(checked)`;default slot 替代 label
|
|
65
|
+
| `AppleCheckbox` | F;`v-model: boolean`、`indeterminate` | `change(checked)`;default slot 替代 label 文本,默认文字在左、开关在右;hint 在下方。 |
|
|
52
66
|
| `AppleRadioGroup` | F;`v-model: string/number/null`、`items`、`inline`、`name` | `change(value)`;原生 radio group。 |
|
|
53
|
-
| `AppleSwitch` | F;`v-model: boolean` | `change(checked)`;default slot 替代 label
|
|
67
|
+
| `AppleSwitch` | F;`v-model: boolean` | `change(checked)`;default slot 替代 label 文本。默认 width: 100%,label 和 hint 在左侧同一列,开关在右侧。 |
|
|
54
68
|
| `AppleSlider` | F;`v-model: number`、`min=0`、`max=100`、`step=1`、`showValue=true`、`formatValue(value)` | `change(value)`;单值原生 range,不是双滑块范围选择。 |
|
|
55
69
|
| `AppleStepper` | F;`v-model: number`、`min=-Infinity`、`max=Infinity`、`step=1` | `change(value)`;减/加按钮及可编辑数值输入;提交时约束范围。 |
|
|
56
70
|
| `AppleSegmentedControl` | F;`v-model: string/number/null`、`items`、`name` | `change(value)`;基于 radio 的单选分段控件,不是 tabs 内容容器。 |
|
|
@@ -58,7 +72,7 @@ Tabs、TabBar、SegmentedControl、DatePicker 日期/时间页签均不使用 Ri
|
|
|
58
72
|
| `AppleColorPicker` | F;`v-model: string='#0071e3'`、`showValue=true` | `change(value)`;自绘色板和 HEX 输入,不打开原生颜色弹窗。 |
|
|
59
73
|
| `AppleUpload` | F;`v-model: File[]`、`accept`、`multiple`、`maxSize=Infinity`、`maxFiles=Infinity`、`capture=user/environment`、`buttonText` | `change(files)`、`reject({file,reason}[])`、`remove(file)`;default slot;maxSize 单位为字节;不发送网络请求。 |
|
|
60
74
|
| `AppleForm` | M;`disabled`、`loading`、`validator(FormData): boolean/string/Promise` | `submit(FormData)`、`invalid({type,message?})`、`reset()`;default slot `{loading}`;实例方法 `validate(): Promise<boolean>`、`submit()`、`reset()`。 |
|
|
61
|
-
| `AppleFormField` | F;`for` | default slot `{id,disabled,required,'aria-invalid','aria-describedby'}
|
|
75
|
+
| `AppleFormField` | F;`for` | default slot `{id,disabled,required,'aria-label','aria-labelledby','aria-invalid','aria-describedby'}`;将 slot 属性绑定到自定义输入,以关联字段名称及提示。 |
|
|
62
76
|
| `AppleOtpInput` | F;`label='验证码'`、`v-model: string`、`length=6`(1–12)、`numeric=true`、`name`、`mask` | `change(value)`、`complete(value)`;`focus(index=0)`;支持粘贴、退格、方向键与验证码自动填充提示。 |
|
|
63
77
|
| `AppleCascader` | F;`v-model: (string/number)[]`、`items: AppleCascaderOption[]`、`placeholder`、`levelLabels: string[]`、`name` | `change(path)`、`complete(path)`;选项递归增加 `children`;不内置行政区划数据。 |
|
|
64
78
|
| `AppleRate` | F;`label='评分'`、`v-model: number`、`max=5`(渲染 1–10)、`readonly`、`allowClear=true`、`name` | `change(value)`;整数星级;allowClear 时再次选择当前值返回 0;不支持半星。 |
|
|
@@ -111,7 +125,6 @@ validator 返回 `true` 才通过;字符串作为错误信息,`false` 显示
|
|
|
111
125
|
| `AppleInfiniteScroll` | `loading`、`error: boolean/string`、`finished`、`disabled`、`distance=120`、`finishedText` | `load(done)`、`retry(done)`;default slot;IntersectionObserver 及手动加载按钮;完成后调用 done,或令 loading 从 true 回到 false。 |
|
|
112
126
|
| `AppleBackTop` | `target: CSS selector=''`、`threshold=300`、`label`、`disabled` | `click(event)`;default slot;空 target 使用 window,达到滚动阈值才显示。 |
|
|
113
127
|
| `AppleFloatingGroup` | `backTop=true`、`threshold=300`、`target`、`label` | default slot 放附加操作,回顶按钮始终排最下;默认固定右下并考虑安全区。 |
|
|
114
|
-
| `AppleMarquee` | `text`、`duration=24`、`paused`、`label` | default slot;duration 单位为秒;带暂停按钮;减少动态效果时停止连续滚动。 |
|
|
115
128
|
| `AppleStatistic` | 必填 `label`;`value: string/number`、`prefix`、`suffix`、`precision=0`、`locale=zh-CN`、`description` | default slot;数值本地化格式,不会自动请求统计数据。 |
|
|
116
129
|
|
|
117
130
|
`AppleColumn = { key: string; label: string; sortable?: boolean; align?: 'left'|'center'|'right'; width?: number|string; minWidth?: number; maxWidth?: number; resizable?: boolean }`。表格 rows 应提供稳定唯一的 `rowKey`。
|
|
@@ -190,6 +203,7 @@ Modal slots:`title`、default `{close}`、footer `{close,confirm,cancel}`。
|
|
|
190
203
|
| `overlays.entries.value` | 当前弹层列表,`Ref<OverlayEntry[]>`。 |
|
|
191
204
|
| `portalTarget.value` | 弹层挂载 DOM 元素。 |
|
|
192
205
|
| `motion.value.set(mode)` | 即时修改全局动效策略。 |
|
|
206
|
+
| `ripple.value.enabled / set(enabled)` | 全局点击波纹开关,默认 true;也可传入 `createAppleUI({ ripple: false })`。切换到减弱动效或系统开启减少动态效果时自动关闭,可手动开启;只有关闭动效时禁止开启。开启 persist 时保存偏好,嵌套 Provider 共享此开关。 |
|
|
193
207
|
| `onMessage(channel,listener)` | 注册监听器,返回取消订阅函数。 |
|
|
194
208
|
| `sendMessage(channel,payload?)` | 返回该 channel 全部监听器的返回值数组。 |
|
|
195
209
|
| `dialog(options)` | 打开 dialog 并返回独立句柄。 |
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# AppleInput API 页面样板
|
|
2
|
+
|
|
3
|
+
当前验收入口:<http://127.0.0.1:5201/component-docs/apple-input>。也可以从组件总览的 AppleInput 卡片底部 AppleLink「代码与 API」进入。第一阶段只注册 AppleInput,未扩面、未提交、未发布,404 与已有工作保持原样。
|
|
4
|
+
|
|
5
|
+
## 当前交互
|
|
6
|
+
|
|
7
|
+
- 独立页面,顶部使用 AppleBreadcrumbs;四边 padding 统一40px。顶部组件演示、左侧 AppleTree 列出全部属性、事件、插槽和方法,点击定位并高亮;支持键盘展开/折叠,不再显示单独的 API tab。总览入口与相邻展开栏的高度、字号、字重、颜色和padding一致。
|
|
8
|
+
- 17 条公开接口:11 个 props、3 个 events、2 个 slots、focus() 方法。均有源码核实的类型、默认值(适用时)、解释和行为边界。
|
|
9
|
+
- 示例按需提供。Vue 原生 v-model 与原生 placeholder 只解释,不另做专门示例;15 个组件相关例子通过 AppleAccordion 展开。
|
|
10
|
+
- 示例标题、功能和操作说明全部放在 Accordion 的展开内容内。
|
|
11
|
+
- 桌面左侧效果、右侧 Vue SFC;720px 以下上下排列。三项输入类型使用 AppleSegmentedControl;五项动效模式使用 AppleSelect,状态切换使用 AppleSwitch,示例容器使用 AppleCard,操作使用 AppleButton。
|
|
12
|
+
- API 文档按页面加载;编译器、CodeMirror、运行资源直到展开示例才加载。任意时刻只有一个编辑器与 iframe,折叠/切换销毁实例,草稿仅保存本页内代码文本,离开页面丢弃。恢复示例返回原始文本。
|
|
13
|
+
- 移除了组件源码编辑 tab。源码提取工具与可选 implementation 契约保留供后续确需源码的示例使用,当前页面不下载源码快照。
|
|
14
|
+
|
|
15
|
+
## 可复用边界
|
|
16
|
+
|
|
17
|
+
`playground/editor/contract.ts` 定义 ComponentDocument:name/source、props/events/slots/methods/notes。ApiEntry 必须提供 id/name/type/description,default 与完整 SFC example 可选。不要为了填满页面给所有原生 API 制作重复示例。
|
|
18
|
+
|
|
19
|
+
`playground/editor/documents.ts` 是轻量注册表,每项提供名称、标签、分组、说明、异步文档 loader,以及可选预览组件。组件总览根据注册表自动显示文档入口;没有注册的组件保持原来的展开区。
|
|
20
|
+
|
|
21
|
+
`playground/views/component-docs/[component].vue` 是共用文件路由:根据 slug 读取注册表、加载文档、生成导航与演示。没有 AppleInput 的专属布局逻辑,也不依赖总览的 ComponentDemo/catalog。删除总览及其演示文件时,独立文档仍可构建。
|
|
22
|
+
|
|
23
|
+
`ComponentDocumentLink.vue` 只负责卡片底部 AppleLink 与 Vue Router 导航。`ComponentWorkshop.vue` 接收 doc prop,统一渲染 API、Accordion、单个活动示例和文本草稿。`LiveVueEditor.vue` 只接收 files、activeFile、baselineFiles,负责官方 REPL、主题、恢复/复制和错误显示。
|
|
24
|
+
|
|
25
|
+
后续接入步骤:从组件真实源码列举接口 → 编写符合契约的文档和必要 SFC 例子 → 提供可选轻量预览 → 注册 slug。页面/入口/编辑器不需要复制或重写。当前注册表只含 AppleInput,待样板验收后再按组件分块实施。
|
|
26
|
+
|
|
27
|
+
## 编译方案、依赖与资源
|
|
28
|
+
|
|
29
|
+
使用 [Vue 官方 @vue/repl](https://github.com/vuejs/repl) 4.7.2、官方 CodeMirror、useStore/Sandbox/compiler-sfc。不自造正则编译器。用户代码在本地浏览器编译,不上传第三方。支持 template、script setup、普通 CSS/scoped CSS、响应式状态及组件库 ESM 导入。
|
|
30
|
+
|
|
31
|
+
[Vuetify Play](https://play.vuetifyjs.com/) 作为交互依据;已检查官方发布页面/入口,使用 Vue REPL 与异步 MonacoWrapper。本样板选择较轻的官方 CodeMirror,避免 Monaco 的额外 CDN 类型加载。
|
|
32
|
+
|
|
33
|
+
开发依赖:固定 @vue/repl 4.7.2、es-module-shims ^2.8.4、esbuild ^0.25.12、postcss ^8.5.28;esbuild/PostCSS 原已作为传递依赖安装,现声明为构建工具直接依赖。未升级无关依赖,不加入组件库生产入口。
|
|
34
|
+
|
|
35
|
+
当前生产 gzip 约:文档数据 4.8KB;共享路由 JS/CSS 3.8KB;展开时编辑器/compiler/CodeMirror JS 417.6KB、CSS 4.3KB;预览 Vue 41.9KB、Apptify runtime 79.6KB、库 CSS 16.2KB、shim 23KB。展开新增约583KB gzip。额外 TS/JSX 转换块约1.05MB gzip,仅相关语法触发时加载。下载缓存关闭后仍保留,运行实例销毁。
|
|
36
|
+
|
|
37
|
+
`tooling/playground-editor.mjs` 将本地库及依赖打包为浏览器 ESM,Vue 单独映射;消费者使用公开 apptify/apptify/style.css,不依赖仓库外路径。模板同步包含注册表、页面、共享编辑器、预览与文档数据。Vite dev/preview 自动给 assets/editor/* 添加公开资源 CORS;静态部署也需设置这些资源的 CORS。
|
|
38
|
+
|
|
39
|
+
## 隔离与限制
|
|
40
|
+
|
|
41
|
+
固定版本 REPL 的 sandbox 收紧为 allow-scripts,其余权限删除,上游结构变化时构建失败,未改官方编译器。opaque iframe 隔离父文档/存储及预览 CSS,普通编译/运行错误在编辑器中展示。CSP 默认禁止资源,允许 inline/blob/本机运行资源;不自动解析任意 npm、不请求 CDN。严格父 CSP 需要兼容 srcdoc、inline 模块与 blob;本样板不修改父服务器策略。
|
|
42
|
+
|
|
43
|
+
iframe 可能共享浏览器进程,同步死循环、超大编译输入、内存耗尽仍可能卡住标签页;刷新可恢复,不能承诺完全隔离。CSP 允许当前 origin 请求,不隔离同源 API 副作用,不运行不可信代码。无 Sass/Less、任意 npm 解析、服务端 API 与文件系统。
|
|
44
|
+
|
|
45
|
+
真实表单导航被禁用;required 例子使用原生 reportValidity() 模拟提交校验。重新编译会 unmount 旧 Vue 应用,代码创建的资源须在 onUnmounted 清理;重新运行重建 iframe,折叠/离开销毁运行 realm。auto-resize=false 避免上游每次 mount 额外注册未清理的 resize handler;CodeMirror 自身一次性共享处理器保留。
|
|
46
|
+
|
|
47
|
+
用户截图中的 import map 报错已修复:useStore 之前同步建立文件/map,以 App.vue 开始编译再切换活动文件,设置 welcomeSFC 防止官方默认欢迎页替换入口。恢复带完整 map 并串行应用。
|
|
48
|
+
|
|
49
|
+
## 验证
|
|
50
|
+
|
|
51
|
+
`tests/e2e/input-workshop.spec.ts` 验证总览底部 AppleLink 导航、直接访问文档路由、无多余 tab、面包屑、40px padding、相邻底栏样式一致性、17 个接口/15 个 Accordion、展开前无编辑器/编译器资源、同一时间一个编辑器、每个例子的实际组件显示、代码修改、编译/运行错误恢复、清空、required/focus、草稿保留/恢复、反复运行、dark 主题、桌面左右/手机上下几何位置、390px 无溢出、折叠/离开销毁。最终生产回归14.6秒通过,pageErrors为空。文档页DOM:展开前441 → 展开764 → 折叠447;编辑器与iframe均为0 → 1 → 0。折叠后保留下载资源缓存。
|
|
52
|
+
|
|
53
|
+
最新截图和原始 DOM/资源数据:`artifacts/input-workshop/api-page-desktop.png`、`api-page-mobile.png`、`metrics-v3.json`。早期弹窗证据保留为历史记录,不代表当前界面。
|
|
54
|
+
|
|
55
|
+
类型检查、生产构建、消费者完整模板/删减模板与库消费验证通过;归档验证目录为`/var/folders/y3/wc0kb5h13yl41wyj6nrf3vv00000gp/T/apptify-package-9m8mVc`。早期全库单元测试179通过、1个既有404动画frames失败;按要求未修改该内容。
|
|
56
|
+
|
|
57
|
+
所有接口与示例说明改用直白中文:先说明用途与操作,再解释必要的边界。树形导航和正文共用 sections.ts 分组契约,不需要逐页维护导航节点。
|
|
58
|
+
|
|
59
|
+
预览动效跟随页面设置,并通过组件库上下文监听系统减少动效偏好。预览根节点应用与 AppleProvider 一致的公共样式和解析后的动效模式;卸载时停止偏好监听。Playwright 验证 full 模式下分段切换存在实际动画,none 模式下没有运行中的动画。
|