@outs-tand-ing/ui 0.0.4 → 0.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.
@@ -0,0 +1,18 @@
1
+ declare var __VLS_6: {}, __VLS_8: {}, __VLS_10: {};
2
+ type __VLS_Slots = {} & {
3
+ header?: (props: typeof __VLS_6) => any;
4
+ } & {
5
+ default?: (props: typeof __VLS_8) => any;
6
+ } & {
7
+ footer?: (props: typeof __VLS_10) => any;
8
+ };
9
+ declare const __VLS_base: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
10
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
11
+ declare const _default: typeof __VLS_export;
12
+ export default _default;
13
+ type __VLS_WithSlots<T, S> = T & {
14
+ new (): {
15
+ $slots: S;
16
+ };
17
+ };
18
+ //# sourceMappingURL=AccessWrapper.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"AccessWrapper.vue.d.ts","sourceRoot":"","sources":["../../src/components/AccessWrapper.vue"],"names":[],"mappings":"AAwJA,QAAA,IAAI,OAAO,IAAU,EAAE,OAAO,IAAU,EAAE,QAAQ,IAAW,CAAE;AAC/D,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC3C;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,GAC5C;IAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,QAAQ,KAAK,GAAG,CAAA;CAAE,CAAC;AAO/C,QAAA,MAAM,UAAU,+QACd,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AACzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
@@ -1,5 +1,5 @@
1
1
  type __VLS_Props = {
2
- size?: 'sm' | 'md' | 'lg';
2
+ size?: 'xs' | 'sm' | 'md' | 'lg';
3
3
  };
4
4
  declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
5
  declare const _default: typeof __VLS_export;
@@ -1 +1 @@
1
- {"version":3,"file":"BrandLogo.vue.d.ts","sourceRoot":"","sources":["../../src/components/BrandLogo.vue"],"names":[],"mappings":"AAYA,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CAC1B,CAAC;AA6BF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
1
+ {"version":3,"file":"BrandLogo.vue.d.ts","sourceRoot":"","sources":["../../src/components/BrandLogo.vue"],"names":[],"mappings":"AAYA,KAAK,WAAW,GAAG;IACjB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAA;CACjC,CAAC;AA6BF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -0,0 +1,22 @@
1
+ type __VLS_Props = {
2
+ axis?: 'x' | 'y' | 'both';
3
+ fadeColor?: string;
4
+ wrapperClass?: string;
5
+ };
6
+ declare var __VLS_1: {};
7
+ type __VLS_Slots = {} & {
8
+ default?: (props: typeof __VLS_1) => any;
9
+ };
10
+ declare const __VLS_base: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {
11
+ axis: "x" | "y" | "both";
12
+ fadeColor: string;
13
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
15
+ declare const _default: typeof __VLS_export;
16
+ export default _default;
17
+ type __VLS_WithSlots<T, S> = T & {
18
+ new (): {
19
+ $slots: S;
20
+ };
21
+ };
22
+ //# sourceMappingURL=ScrollableArea.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ScrollableArea.vue.d.ts","sourceRoot":"","sources":["../../src/components/ScrollableArea.vue"],"names":[],"mappings":"AA0FA,KAAK,WAAW,GAAG;IACf,IAAI,CAAC,EAAE,GAAG,GAAG,GAAG,GAAG,MAAM,CAAA;IACzB,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,CAAC;AAoJJ,QAAA,IAAI,OAAO,IAAW,CAAE;AACxB,KAAK,WAAW,GAAG,EAAE,GACnB;IAAE,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,OAAO,KAAK,GAAG,CAAA;CAAE,CAAC;AAO/C,QAAA,MAAM,UAAU;UAhKL,GAAG,GAAG,GAAG,GAAG,MAAM;eACb,MAAM;6EAkKpB,CAAC;AACH,QAAA,MAAM,YAAY,EAAS,eAAe,CAAC,OAAO,UAAU,EAAE,WAAW,CAAC,CAAC;wBACtD,OAAO,YAAY;AAAxC,wBAAyC;AAWzC,KAAK,eAAe,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IAChC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KACV,CAAA;CACD,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
- export { default as PinkBox } from './components/PinkBox.vue';
2
1
  export { default as BrandLogo } from './components/BrandLogo.vue';
2
+ export { default as AccessWrapper } from './components/AccessWrapper.vue';
3
+ export { default as ScrollableArea } from './components/ScrollableArea.vue';
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,0BAA0B,CAAA;AAC7D,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,4BAA4B,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,4BAA4B,CAAA;AACjE,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,gCAAgC,CAAA;AACzE,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,iCAAiC,CAAA"}
package/dist/index.js CHANGED
@@ -1,53 +1,154 @@
1
- import { defineComponent as s, openBlock as _, createElementBlock as i, toDisplayString as p, normalizeClass as u } from "vue";
2
- const l = /* @__PURE__ */ s({
3
- __name: "PinkBox",
4
- props: {
5
- label: { type: String, required: !1 }
6
- },
7
- setup(n, { expose: t }) {
8
- t();
9
- const e = {};
10
- return Object.defineProperty(e, "__isScriptSetup", { enumerable: !1, value: !0 }), e;
11
- }
12
- }), a = (n, t) => {
13
- const e = n.__vccOpts || n;
14
- for (const [o, r] of t)
15
- e[o] = r;
16
- return e;
17
- }, d = { class: "bg-pink-500 text-white rounded-lg p-4 font-medium" };
18
- function f(n, t, e, o, r, c) {
19
- return _(), i(
20
- "div",
21
- d,
22
- p(e.label ?? "PinkBox"),
23
- 1
24
- /* TEXT */
25
- );
1
+ import { computed as e, createCommentVNode as t, createElementBlock as n, createElementVNode as r, createVNode as i, defineComponent as a, normalizeClass as o, normalizeStyle as s, onMounted as c, onUnmounted as l, openBlock as u, ref as d, renderSlot as f } from "vue";
2
+ //#region src/components/BrandLogo.vue?vue&type=script&setup=true&lang.ts
3
+ var p = /* @__PURE__ */ a({
4
+ __name: "BrandLogo",
5
+ props: { size: {
6
+ type: String,
7
+ required: !1
8
+ } },
9
+ setup(e, { expose: t }) {
10
+ t();
11
+ let n = {};
12
+ return Object.defineProperty(n, "__isScriptSetup", {
13
+ enumerable: !1,
14
+ value: !0
15
+ }), n;
16
+ }
17
+ }), m = (e, t) => {
18
+ let n = e.__vccOpts || e;
19
+ for (let [e, r] of t) n[e] = r;
20
+ return n;
21
+ };
22
+ //#endregion
23
+ //#region src/components/BrandLogo.vue
24
+ function h(e, t, r, i, a, s) {
25
+ return u(), n("span", { class: o(["font-posterama", {
26
+ "text-base": r.size === "xs",
27
+ "text-xl": r.size === "sm",
28
+ "text-3xl": !r.size || r.size === "md",
29
+ "text-5xl": r.size === "lg"
30
+ }]) }, "OUTSTANDING", 2);
31
+ }
32
+ var g = /* @__PURE__ */ m(p, [["render", h], ["__file", "/Users/kemal/Desktop/Kite/_Code/outs/ui/src/components/BrandLogo.vue"]]), _ = /* @__PURE__ */ a({
33
+ __name: "AccessWrapper",
34
+ setup(e, { expose: t }) {
35
+ t();
36
+ let n = d(null), r = d(!0), i = () => r.value = document.documentElement.scrollHeight > window.innerHeight + 2;
37
+ c(() => {
38
+ if (i(), window.addEventListener("scroll", i, { passive: !0 }), window.addEventListener("resize", i, { passive: !0 }), n.value) {
39
+ let e = n.value.offsetHeight;
40
+ document.documentElement.style.setProperty("--access-footer-h", `${e}px`);
41
+ }
42
+ }), l(() => {
43
+ window.removeEventListener("scroll", i), window.removeEventListener("resize", i);
44
+ });
45
+ let a = {
46
+ footerRef: n,
47
+ canScroll: r,
48
+ update: i,
49
+ BrandLogo: g
50
+ };
51
+ return Object.defineProperty(a, "__isScriptSetup", {
52
+ enumerable: !1,
53
+ value: !0
54
+ }), a;
55
+ }
56
+ }), v = { class: "min-h-screen bg-gray-50 flex flex-col" }, y = { class: "pt-[var(--access-pt)] pb-4 flex flex-col items-center gap-4" }, b = { href: "/" }, x = { class: "flex-1 flex items-center justify-center p-4 pb-[var(--access-footer-h)]" }, S = {
57
+ ref: "footerRef",
58
+ class: "fixed bottom-0 left-0 right-0 z-10"
59
+ }, C = { class: "bg-gray-50" };
60
+ function w(e, t, a, s, c, l) {
61
+ return u(), n("div", v, [
62
+ r("div", y, [r("a", b, [i(s.BrandLogo, { class: "text-gray-900" })]), f(e.$slots, "header")]),
63
+ r("div", x, [f(e.$slots, "default")]),
64
+ r("div", S, [r("div", {
65
+ class: o(["pointer-events-none h-10 transition-opacity duration-200", s.canScroll ? "opacity-100" : "opacity-0"]),
66
+ style: { background: "linear-gradient(to top, var(--color-surface, #f9fafb), transparent)" }
67
+ }, null, 2), r("div", C, [f(e.$slots, "footer")])], 512)
68
+ ]);
26
69
  }
27
- const g = /* @__PURE__ */ a(l, [["render", f], ["__file", "/Users/kemal/Desktop/Kite/_Code/outs/ui/src/components/PinkBox.vue"]]), m = /* @__PURE__ */ s({
28
- __name: "BrandLogo",
29
- props: {
30
- size: { type: String, required: !1 }
31
- },
32
- setup(n, { expose: t }) {
33
- t();
34
- const e = {};
35
- return Object.defineProperty(e, "__isScriptSetup", { enumerable: !1, value: !0 }), e;
36
- }
70
+ var T = /* @__PURE__ */ m(_, [["render", w], ["__file", "/Users/kemal/Desktop/Kite/_Code/outs/ui/src/components/AccessWrapper.vue"]]), E = /* @__PURE__ */ a({
71
+ __name: "ScrollableArea",
72
+ props: {
73
+ axis: {
74
+ type: String,
75
+ required: !1,
76
+ default: "y"
77
+ },
78
+ fadeColor: {
79
+ type: String,
80
+ required: !1,
81
+ default: "white"
82
+ },
83
+ wrapperClass: {
84
+ type: String,
85
+ required: !1
86
+ }
87
+ },
88
+ setup(t, { expose: n }) {
89
+ n();
90
+ let r = t, i = e(() => r.axis === "x" ? "overflow-x-auto overflow-y-hidden" : r.axis === "both" ? "overflow-auto" : "overflow-y-auto overflow-x-hidden"), a = (e) => ({ background: `linear-gradient(${e}, ${r.fadeColor}, transparent)` }), o = d(null), s = d(!1), u = d(!1), f = d(!1), p = d(!1), m = () => {
91
+ let e = o.value;
92
+ e && (r.axis !== "x" && (s.value = e.scrollTop > 2, u.value = e.scrollTop + e.clientHeight < e.scrollHeight - 2), r.axis !== "y" && (f.value = e.scrollLeft > 2, p.value = e.scrollLeft + e.clientWidth < e.scrollWidth - 2));
93
+ }, h = m, g = null;
94
+ c(() => {
95
+ m(), o.value && (g = new ResizeObserver(m), g.observe(o.value));
96
+ }), l(() => g?.disconnect());
97
+ let _ = {
98
+ props: r,
99
+ scrollerClass: i,
100
+ fadeStyle: a,
101
+ scroller: o,
102
+ canScrollUp: s,
103
+ canScrollDown: u,
104
+ canScrollLeft: f,
105
+ canScrollRight: p,
106
+ update: m,
107
+ onScroll: h,
108
+ get ro() {
109
+ return g;
110
+ },
111
+ set ro(e) {
112
+ g = e;
113
+ }
114
+ };
115
+ return Object.defineProperty(_, "__isScriptSetup", {
116
+ enumerable: !1,
117
+ value: !0
118
+ }), _;
119
+ }
37
120
  });
38
- function x(n, t, e, o, r, c) {
39
- return _(), i(
40
- "span",
41
- {
42
- class: u(["font-posterama text-gray-900", { "text-xl": e.size === "sm", "text-3xl": !e.size || e.size === "md", "text-5xl": e.size === "lg" }])
43
- },
44
- "OUTSTANDING",
45
- 2
46
- /* CLASS */
47
- );
121
+ //#endregion
122
+ //#region src/components/ScrollableArea.vue
123
+ function D(e, i, a, c, l, d) {
124
+ return u(), n("div", { class: o(["relative overflow-hidden", a.wrapperClass]) }, [
125
+ r("div", {
126
+ ref: "scroller",
127
+ class: o(["size-full hide-scroll", c.scrollerClass]),
128
+ onScroll: i[0] ||= (...e) => c.onScroll && c.onScroll(...e)
129
+ }, [f(e.$slots, "default")], 34),
130
+ a.axis === "x" ? t("v-if", !0) : (u(), n("div", {
131
+ key: 0,
132
+ class: o(["pointer-events-none absolute left-0 right-0 top-0 h-10 transition-opacity duration-200", c.canScrollUp ? "opacity-100" : "opacity-0"]),
133
+ style: s(c.fadeStyle("to bottom"))
134
+ }, null, 6)),
135
+ a.axis === "x" ? t("v-if", !0) : (u(), n("div", {
136
+ key: 1,
137
+ class: o(["pointer-events-none absolute left-0 right-0 bottom-0 h-10 transition-opacity duration-200", c.canScrollDown ? "opacity-100" : "opacity-0"]),
138
+ style: s(c.fadeStyle("to top"))
139
+ }, null, 6)),
140
+ a.axis === "y" ? t("v-if", !0) : (u(), n("div", {
141
+ key: 2,
142
+ class: o(["pointer-events-none absolute top-0 bottom-0 left-0 w-10 transition-opacity duration-200", c.canScrollLeft ? "opacity-100" : "opacity-0"]),
143
+ style: s(c.fadeStyle("to right"))
144
+ }, null, 6)),
145
+ a.axis === "y" ? t("v-if", !0) : (u(), n("div", {
146
+ key: 3,
147
+ class: o(["pointer-events-none absolute top-0 bottom-0 right-0 w-10 transition-opacity duration-200", c.canScrollRight ? "opacity-100" : "opacity-0"]),
148
+ style: s(c.fadeStyle("to left"))
149
+ }, null, 6))
150
+ ], 2);
48
151
  }
49
- const B = /* @__PURE__ */ a(m, [["render", x], ["__file", "/Users/kemal/Desktop/Kite/_Code/outs/ui/src/components/BrandLogo.vue"]]);
50
- export {
51
- B as BrandLogo,
52
- g as PinkBox
53
- };
152
+ var O = /* @__PURE__ */ m(E, [["render", D], ["__file", "/Users/kemal/Desktop/Kite/_Code/outs/ui/src/components/ScrollableArea.vue"]]);
153
+ //#endregion
154
+ export { T as AccessWrapper, g as BrandLogo, O as ScrollableArea };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@outs-tand-ing/ui",
3
- "version": "0.0.4",
3
+ "version": "0.2.0",
4
4
  "description": "Shared Vue components, icons, and design tokens for Outs",
5
5
  "type": "module",
6
6
  "sideEffects": [
@@ -13,7 +13,8 @@
13
13
  "types": "./dist/index.d.ts",
14
14
  "import": "./dist/index.js"
15
15
  },
16
- "./typography.css": "./src/assets/typography.css"
16
+ "./typography.css": "./src/assets/typography.css",
17
+ "./components.css": "./src/assets/components.css"
17
18
  },
18
19
  "files": [
19
20
  "dist",
@@ -41,12 +42,12 @@
41
42
  "vue": "^3.5.0"
42
43
  },
43
44
  "devDependencies": {
44
- "@vitejs/plugin-vue": "^5.2.0",
45
+ "@vitejs/plugin-vue": "^6.0.5",
45
46
  "eslint": "^10.1.0",
46
- "eslint-plugin-vue": "^10.1.0",
47
+ "eslint-plugin-vue": "^10.8.0",
47
48
  "typescript": "^6.0.2",
48
- "typescript-eslint": "^8.32.0",
49
- "vite": "^6.3.0",
49
+ "typescript-eslint": "^8.58.0",
50
+ "vite": "^8.0.3",
50
51
  "vue": "^3.5.31",
51
52
  "vue-tsc": "^3.2.6"
52
53
  }
@@ -0,0 +1,66 @@
1
+ /* ── Scroll-fade: vertical ── */
2
+ @utility scroll-fade {
3
+ --sf-size: 1.5rem;
4
+ --sf-top: 0;
5
+ --sf-bottom: 0;
6
+ --sf-color: var(--color-surface);
7
+
8
+ &::before,
9
+ &::after {
10
+ content: '';
11
+ display: block;
12
+ height: var(--sf-size);
13
+ position: sticky;
14
+ left: 0;
15
+ right: 0;
16
+ pointer-events: none;
17
+ z-index: 1;
18
+ }
19
+
20
+ &::before {
21
+ top: var(--sf-top);
22
+ background: linear-gradient(to bottom, var(--sf-color), transparent);
23
+ margin-bottom: calc(-1 * var(--sf-size));
24
+ }
25
+
26
+ &::after {
27
+ bottom: var(--sf-bottom);
28
+ background: linear-gradient(to top, var(--sf-color), transparent);
29
+ margin-top: calc(-1 * var(--sf-size));
30
+ }
31
+ }
32
+
33
+ /* ── Scroll-fade: horizontal ── */
34
+ @utility scroll-fade-x {
35
+ --sf-size: 1.5rem;
36
+ --sf-color: var(--color-surface);
37
+
38
+ &::before,
39
+ &::after {
40
+ content: '';
41
+ flex-shrink: 0;
42
+ width: var(--sf-size);
43
+ position: sticky;
44
+ top: 0;
45
+ align-self: stretch;
46
+ pointer-events: none;
47
+ z-index: 1;
48
+ }
49
+
50
+ &::before {
51
+ left: 0;
52
+ background: linear-gradient(to right, var(--sf-color), transparent);
53
+ margin-right: calc(-1 * var(--sf-size));
54
+ }
55
+
56
+ &::after {
57
+ right: 0;
58
+ background: linear-gradient(to left, var(--sf-color), transparent);
59
+ margin-left: calc(-1 * var(--sf-size));
60
+ }
61
+ }
62
+
63
+ /* ── Scroll-fade modifiers (work with both axes) ── */
64
+ @utility sf-size-* {
65
+ --sf-size: --value(--spacing);
66
+ }
@@ -5,3 +5,43 @@
5
5
  font-style: normal;
6
6
  font-display: swap;
7
7
  }
8
+
9
+ .text-trim {
10
+ text-box: trim-both cap alphabetic;
11
+ }
12
+
13
+ @utility text-trim-start {
14
+ text-box: trim-start cap alphabetic;
15
+ }
16
+
17
+ @utility text-trim-end {
18
+ text-box: trim-end cap alphabetic;
19
+ }
20
+
21
+ @layer base {
22
+ h1,
23
+ h2,
24
+ h3,
25
+ h4,
26
+ h5,
27
+ h6 {
28
+ font-family: var(--font-heading);
29
+ color: var(--color-text-primary);
30
+ font-weight: 900;
31
+ line-height: 1.1;
32
+ letter-spacing: -0.02em;
33
+ transition: color 200ms ease, font-family 200ms ease;
34
+ }
35
+
36
+ h1 { font-size: clamp(2rem, 5vw, 3.5rem); }
37
+
38
+ h2 { font-size: clamp(1.5rem, 3.5vw, 2.25rem); }
39
+
40
+ h3 { font-size: clamp(1.25rem, 2.5vw, 1.75rem); letter-spacing: -0.01em; }
41
+
42
+ h4 { font-size: 1.25rem; letter-spacing: 0; font-weight: 700; }
43
+
44
+ h5 { font-size: 1rem; letter-spacing: 0; font-weight: 700; }
45
+
46
+ h6 { font-size: 0.875rem; letter-spacing: 0; font-weight: 600; color: var(--color-text-secondary); }
47
+ }
@@ -0,0 +1,46 @@
1
+ <template>
2
+ <div class="min-h-screen bg-gray-50 flex flex-col">
3
+ <div class="pt-[var(--access-pt)] pb-4 flex flex-col items-center gap-4">
4
+ <a href="/"><BrandLogo class="text-gray-900" /></a>
5
+ <slot name="header" />
6
+ </div>
7
+ <div class="flex-1 flex items-center justify-center p-4 pb-[var(--access-footer-h)]">
8
+ <slot />
9
+ </div>
10
+ <div ref="footerRef" class="fixed bottom-0 left-0 right-0 z-10">
11
+ <div
12
+ class="pointer-events-none h-10 transition-opacity duration-200"
13
+ :class="canScroll ? 'opacity-100' : 'opacity-0'"
14
+ :style="{ background: 'linear-gradient(to top, var(--color-surface, #f9fafb), transparent)' }"
15
+ />
16
+ <div class="bg-gray-50">
17
+ <slot name="footer" />
18
+ </div>
19
+ </div>
20
+ </div>
21
+ </template>
22
+
23
+ <script setup lang="ts">
24
+ import { ref, onMounted, onUnmounted } from 'vue'
25
+ import BrandLogo from './BrandLogo.vue'
26
+
27
+ const footerRef = ref<HTMLElement | null>(null)
28
+ const canScroll = ref(true)
29
+
30
+ const update = () => (canScroll.value = document.documentElement.scrollHeight > window.innerHeight + 2)
31
+
32
+ onMounted(() => {
33
+ update()
34
+ window.addEventListener('scroll', update, { passive: true })
35
+ window.addEventListener('resize', update, { passive: true })
36
+ if (footerRef.value) {
37
+ const h = footerRef.value.offsetHeight
38
+ document.documentElement.style.setProperty('--access-footer-h', `${h}px`)
39
+ }
40
+ })
41
+
42
+ onUnmounted(() => {
43
+ window.removeEventListener('scroll', update)
44
+ window.removeEventListener('resize', update)
45
+ })
46
+ </script>
@@ -1,9 +1,9 @@
1
1
  <template>
2
- <span class="font-posterama text-gray-900" :class="{ 'text-xl': size === 'sm', 'text-3xl': !size || size === 'md', 'text-5xl': size === 'lg' }">OUTSTANDING</span>
2
+ <span class="font-posterama" :class="{ 'text-base': size === 'xs', 'text-xl': size === 'sm', 'text-3xl': !size || size === 'md', 'text-5xl': size === 'lg' }">OUTSTANDING</span>
3
3
  </template>
4
4
 
5
5
  <script setup lang="ts">
6
6
  defineProps<{
7
- size?: 'sm' | 'md' | 'lg'
7
+ size?: 'xs' | 'sm' | 'md' | 'lg'
8
8
  }>()
9
9
  </script>
@@ -0,0 +1,85 @@
1
+ <template>
2
+ <div class="relative overflow-hidden" :class="wrapperClass">
3
+ <div ref="scroller" class="size-full hide-scroll" :class="scrollerClass" @scroll="onScroll">
4
+ <slot />
5
+ </div>
6
+ <div
7
+ v-if="axis !== 'x'"
8
+ class="pointer-events-none absolute left-0 right-0 top-0 h-10 transition-opacity duration-200"
9
+ :class="canScrollUp ? 'opacity-100' : 'opacity-0'"
10
+ :style="fadeStyle('to bottom')"
11
+ />
12
+ <div
13
+ v-if="axis !== 'x'"
14
+ class="pointer-events-none absolute left-0 right-0 bottom-0 h-10 transition-opacity duration-200"
15
+ :class="canScrollDown ? 'opacity-100' : 'opacity-0'"
16
+ :style="fadeStyle('to top')"
17
+ />
18
+ <div
19
+ v-if="axis !== 'y'"
20
+ class="pointer-events-none absolute top-0 bottom-0 left-0 w-10 transition-opacity duration-200"
21
+ :class="canScrollLeft ? 'opacity-100' : 'opacity-0'"
22
+ :style="fadeStyle('to right')"
23
+ />
24
+ <div
25
+ v-if="axis !== 'y'"
26
+ class="pointer-events-none absolute top-0 bottom-0 right-0 w-10 transition-opacity duration-200"
27
+ :class="canScrollRight ? 'opacity-100' : 'opacity-0'"
28
+ :style="fadeStyle('to left')"
29
+ />
30
+ </div>
31
+ </template>
32
+
33
+ <script setup lang="ts">
34
+ import { computed, ref, onMounted, onUnmounted } from 'vue'
35
+
36
+ const props = withDefaults(
37
+ defineProps<{
38
+ axis?: 'x' | 'y' | 'both'
39
+ fadeColor?: string
40
+ wrapperClass?: string
41
+ }>(),
42
+ { axis: 'y', fadeColor: 'white' },
43
+ )
44
+
45
+ const scrollerClass = computed(() => {
46
+ if (props.axis === 'x') return 'overflow-x-auto overflow-y-hidden'
47
+ if (props.axis === 'both') return 'overflow-auto'
48
+ return 'overflow-y-auto overflow-x-hidden'
49
+ })
50
+
51
+ const fadeStyle = (direction: string) => ({
52
+ background: `linear-gradient(${direction}, ${props.fadeColor}, transparent)`,
53
+ })
54
+
55
+ const scroller = ref<HTMLElement | null>(null)
56
+ const canScrollUp = ref(false)
57
+ const canScrollDown = ref(false)
58
+ const canScrollLeft = ref(false)
59
+ const canScrollRight = ref(false)
60
+
61
+ const update = () => {
62
+ const el = scroller.value
63
+ if (!el) return
64
+ if (props.axis !== 'x') {
65
+ canScrollUp.value = el.scrollTop > 2
66
+ canScrollDown.value = el.scrollTop + el.clientHeight < el.scrollHeight - 2
67
+ }
68
+ if (props.axis !== 'y') {
69
+ canScrollLeft.value = el.scrollLeft > 2
70
+ canScrollRight.value = el.scrollLeft + el.clientWidth < el.scrollWidth - 2
71
+ }
72
+ }
73
+
74
+ const onScroll = update
75
+
76
+ let ro: ResizeObserver | null = null
77
+ onMounted(() => {
78
+ update()
79
+ if (scroller.value) {
80
+ ro = new ResizeObserver(update)
81
+ ro.observe(scroller.value)
82
+ }
83
+ })
84
+ onUnmounted(() => ro?.disconnect())
85
+ </script>
package/src/index.ts CHANGED
@@ -1,2 +1,3 @@
1
- export { default as PinkBox } from './components/PinkBox.vue'
2
1
  export { default as BrandLogo } from './components/BrandLogo.vue'
2
+ export { default as AccessWrapper } from './components/AccessWrapper.vue'
3
+ export { default as ScrollableArea } from './components/ScrollableArea.vue'
@@ -1,7 +0,0 @@
1
- type __VLS_Props = {
2
- label?: string;
3
- };
4
- declare const __VLS_export: import("vue").DefineComponent<__VLS_Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<__VLS_Props> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
5
- declare const _default: typeof __VLS_export;
6
- export default _default;
7
- //# sourceMappingURL=PinkBox.vue.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"PinkBox.vue.d.ts","sourceRoot":"","sources":["../../src/components/PinkBox.vue"],"names":[],"mappings":"AAcA,KAAK,WAAW,GAAG;IACjB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf,CAAC;AA6BF,QAAA,MAAM,YAAY,kSAEhB,CAAC;wBACkB,OAAO,YAAY;AAAxC,wBAAyC"}
@@ -1,11 +0,0 @@
1
- <script setup lang="ts">
2
- defineProps<{
3
- label?: string
4
- }>()
5
- </script>
6
-
7
- <template>
8
- <div class="bg-pink-500 text-white rounded-lg p-4 font-medium">
9
- {{ label ?? 'PinkBox' }}
10
- </div>
11
- </template>