@funhub/platform 0.1.29 → 0.1.31

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.
@@ -3,6 +3,6 @@ import { ChannelListProps } from "./schema.mjs";
3
3
  import * as react_jsx_runtime0 from "react/jsx-runtime";
4
4
 
5
5
  //#region components/biz/business/channel-list/client.d.ts
6
- declare function BasicNavBarClient(props: ChannelListProps): react_jsx_runtime0.JSX.Element;
6
+ declare function BasicChannelListClient(props: ChannelListProps): react_jsx_runtime0.JSX.Element;
7
7
  //#endregion
8
- export { BasicNavBarClient };
8
+ export { BasicChannelListClient };
@@ -1,2 +1,2 @@
1
1
 
2
- "use client";import{mergeStyles as e}from"../../utils/styles/helpers.mjs";import{pxToVw as t}from"../../../../utils/helper.mjs";import{Box as n}from"../../../ui/box.mjs";import{useSticky as r}from"../../../../hooks/use-sticky.mjs";import i from"../../../ui/link.mjs";import{urlPrefix as a}from"../../../../constants/url-prefix.mjs";import o,{loadHiddenChannelIdsFromStorage as s}from"./channel-filter-dialog.mjs";import{defaultProps as c}from"./default-props.mjs";import{useEffect as l,useMemo as u,useState as d}from"react";import{clsx as f}from"clsx";import{Fragment as p,jsx as m,jsxs as h}from"react/jsx-runtime";const g={};function _(e,t){return t===0?`/`:`${a.CHANNEL}/${encodeURIComponent(e.name)}`}function v(a){let{styles:v,events:y,...b}=a,x=b||g,S={...c,...x},{channelItemHeight:C,channelItemFontSize:w,channelItemActiveFontSize:T,channelItemGap:E}=S,[D,O]=d(!1),{isSticky:k,ref:A}=r(),[j,M]=d(S.list),N=u(()=>S.currentChannelId??null,[S.currentChannelId]);l(()=>{let e=s();M(e?.length?S.list.filter(t=>!e.includes(t.name)):S.list)},[S.list]);let P=e=>{M(e)},F=(e,t)=>{y?.onChannelChange?.(e,t)},I=v?e(v,{}):void 0;return h(p,{children:[k&&m(n,{className:`w-full`,style:{height:t(44)}}),m(n,{as:`nav`,ref:A,className:f(`w-full transition-all duration-200`,!S.isFullfeed&&k&&`fixed top-0 left-0 right-0 z-50`,S.isFullfeed&&`fixed top-[54px] left-0 z-10 w-full`,!S.isFullfeed&&`bg-bg1`),style:I,children:m(n,{className:`relative flex items-center h-[44px]`,children:m(n,{className:`flex-1 overflow-x-auto overflow-y-hidden [&::-webkit-scrollbar]:hidden`,style:{scrollbarWidth:`none`,msOverflowStyle:`none`,WebkitOverflowScrolling:`touch`},children:m(n,{className:`flex items-center h-full`,style:{paddingLeft:t(16),paddingRight:t(16),gap:t(E)},children:j.map((e,n)=>{let r=N===e.name||N===null&&n===0;return m(i,{href:_(e,n),className:f(`whitespace-nowrap cursor-pointer transition-all duration-200`,`flex items-center justify-center`),style:{height:t(C),fontSize:t(r?T:w),fontWeight:r?`bold`:`normal`,color:r?`var(--color-theme5)`:`var(--color-text2)`},onClick:()=>F(e,n),children:e.name},e.name||`channel-${n}`)})})})})}),m(o,{open:D,onOpenChange:O,channels:S.list,currentChannelId:N,onChannelClick:F,onChannelsChange:P})]})}export{v as default};
2
+ "use client";import{mergeStyles as e}from"../../utils/styles/helpers.mjs";import{Box as t}from"../../../ui/box.mjs";import{useSticky as n}from"../../../../hooks/use-sticky.mjs";import r from"../../../ui/link.mjs";import{urlPrefix as i}from"../../../../constants/url-prefix.mjs";import a,{loadHiddenChannelIdsFromStorage as o}from"./channel-filter-dialog.mjs";import{defaultProps as s}from"./default-props.mjs";import{useEffect as c,useMemo as l,useState as u}from"react";import{clsx as d}from"clsx";import{Fragment as f,jsx as p,jsxs as m}from"react/jsx-runtime";const h={};function g(e,t){return t===0?`/`:`${i.CHANNEL}/${encodeURIComponent(e.name)}`}function _(i){let{styles:_,events:v,...y}=i,b=y||h,x={...s,...b},[S,C]=u(!1),{isSticky:w,ref:T}=n(),[E,D]=u(x.list),O=l(()=>x.currentChannelId??null,[x.currentChannelId]);c(()=>{let e=o();D(e?.length?x.list.filter(t=>!e.includes(t.name)):x.list)},[x.list]);let k=e=>{D(e)},A=(e,t)=>{v?.onChannelChange?.(e,t)},j=_?e(_,{}):void 0;return m(f,{children:[w&&p(t,{className:`w-full h-11`}),p(t,{as:`nav`,ref:T,className:d(`w-full transition-all duration-200`,!x.isFullfeed&&w&&`fixed top-0 left-0 right-0 z-50`,x.isFullfeed&&`fixed top-[54px] left-0 z-10 w-full`,!x.isFullfeed&&`bg-bg1`),style:j,children:p(t,{className:`relative flex items-center h-[44px]`,children:p(t,{className:`flex-1 overflow-x-auto overflow-y-hidden [&::-webkit-scrollbar]:hidden`,style:{scrollbarWidth:`none`,msOverflowStyle:`none`,WebkitOverflowScrolling:`touch`},children:p(t,{className:`flex items-center h-full w-4 h-4 gap-4`,children:E.map((e,t)=>{let n=O===e.name||O===null&&t===0;return p(r,{href:g(e,t),className:d(`whitespace-nowrap cursor-pointer transition-all duration-200`,`flex items-center justify-center h-11`,`${n?`text-xl`:`text-base`}`),style:{fontWeight:n?`bold`:`normal`,color:n?`var(--color-theme5)`:`var(--color-text2)`},onClick:()=>A(e,t),children:e.name},e.name||`channel-${t}`)})})})})}),p(a,{open:S,onOpenChange:C,channels:x.list,currentChannelId:O,onChannelClick:A,onChannelsChange:k})]})}export{_ as default};
@@ -1,2 +1,2 @@
1
1
 
2
- const e={currentChannelId:null,channelItemHeight:44,channelItemFontSize:16,channelItemActiveFontSize:20,channelItemGap:16,isFullfeed:!1,list:[]};export{e as defaultProps};
2
+ const e={currentChannelId:null,isFullfeed:!1,list:[]};export{e as defaultProps};
@@ -2,12 +2,12 @@
2
2
  import { SchemaHasDefaultValue } from "../../../../utils/schema/schema.mjs";
3
3
  import { DefineMaterialOption } from "../../../../utils/schema/material.mjs";
4
4
  import "../../../../utils/schema/index.mjs";
5
- import { BasicNavBarClient } from "./client.mjs";
5
+ import { BasicChannelListClient } from "./client.mjs";
6
6
  import * as zod from "zod";
7
7
  import * as zod_v4_core0 from "zod/v4/core";
8
8
 
9
9
  //#region components/biz/business/channel-list/material.d.ts
10
- declare const channelListMaterial: DefineMaterialOption<typeof BasicNavBarClient, typeof BasicNavBarClient, zod.ZodObject<{
10
+ declare const channelListMaterial: DefineMaterialOption<typeof BasicChannelListClient, typeof BasicChannelListClient, zod.ZodObject<{
11
11
  list: zod.ZodOptional<zod.ZodArray<zod.ZodObject<{
12
12
  name: zod.ZodOptional<zod.ZodString>;
13
13
  icon: zod.ZodOptional<zod.ZodString>;
@@ -0,0 +1,2 @@
1
+
2
+ import{Image as e}from"../../../ui/image.mjs";import{Box as t}from"../../../ui/box.mjs";import{Text as n}from"../../../ui/text.mjs";import r from"../../../ui/link.mjs";import i from"../../../../assets/icons/view.mjs";import{jsx as a,jsxs as o}from"react/jsx-runtime";function s(e){if(e.duration===void 0||e.duration===null||e.duration===``)return null;let t=String(e.duration);if(t.includes(`集`))return t.startsWith(`全`)?t:`全${t.replace(/\D/g,``)}集`;let n=Number(e.duration);if(!Number.isNaN(n)&&n>0){let e=Math.floor(n),t=Math.floor(e/3600),r=Math.floor(e%3600/60),i=e%60,a=e=>String(e).padStart(2,`0`);return t>0?`${a(t)}:${a(r)}:${a(i)}`:`${a(r)}:${a(i)}`}return String(e.duration)}function c(e){if(e==null||e===``)return null;let t=Number(e);if(Number.isNaN(t))return String(e);if(t<1e3)return String(t);if(t<1e6){let e=(t/1e3).toFixed(1);return e.endsWith(`.0`)?`${e.slice(0,-2)}K`:`${e}K`}else{let e=(t/1e6).toFixed(1);return e.endsWith(`.0`)?`${e.slice(0,-2)}M`:`${e}M`}}function l(e){let t=e.tag_image||e.tag_image_url||e.tagImage||e.tagImageUrl;return t?String(t):null}function u({data:u}){return u?a(t,{children:(Array.isArray(u)?u:[u]).map(u=>{let d=u.id?`/video/${u.id}/${u.title?encodeURIComponent(u.title):``}`:`#`,f=(e=>e===1?{text:`新剧`,fromColor:`#FD4C5E`,toColor:`#F05D19`,textColor:`#FFFFFF`}:e===2?{text:`热门`,fromColor:`#FFE485`,toColor:`#CF8125`,textColor:`#674100`}:null)(u.superscript),p=u.tag||f?.text,m=l(u),h=f?{from:f.fromColor,to:f.toColor,text:f.textColor}:{from:`#FD4C5E`,to:`#F05D19`,text:`#FFFFFF`},g=s(u),_=c(u.playCount);return a(t,{children:o(r,{href:d,children:[o(t,{className:`relative w-full overflow-hidden rounded-[12px] bg-neutral-800`,style:{aspectRatio:`16/9`},children:[u.cover&&a(e,{src:u.cover,alt:u.title,fill:!0,objectFit:`cover`}),m&&a(t,{className:`absolute right-0 top-0 z-10 h-[24px] w-[64px]`,children:a(e,{src:m,alt:u.title,fill:!0,objectFit:`contain`})}),!m&&p&&a(t,{className:`absolute right-0 top-0 flex items-center justify-center z-10`,style:{height:`24px`,padding:`0 10px`,borderTopRightRadius:`12px`,borderBottomLeftRadius:`18px`,background:`linear-gradient(to right, ${h.from}, ${h.to})`,color:h.text},children:a(n,{as:`span`,className:`text-[13px] font-medium leading-none`,children:p})}),a(t,{className:`absolute inset-x-0 bottom-0 h-[40px] bg-gradient-to-t from-black/80 to-transparent z-0 pointer-events-none`}),_&&o(t,{className:`absolute bottom-0 left-[8px] mb-[6px] z-10 flex items-center gap-[4px]`,children:[a(i,{className:`h-[14px] w-[14px] text-white`}),a(n,{as:`span`,className:`text-[12px] font-medium text-white drop-shadow-md`,children:_})]}),g&&a(t,{className:`absolute bottom-0 right-[8px] mb-[6px] z-10 flex items-center`,children:a(n,{as:`span`,className:`text-[12px] font-medium text-white drop-shadow-md`,children:g})})]}),o(t,{className:`flex items-center justify-between gap-[12px] pt-[10px] px-2`,children:[o(t,{className:`flex-1 min-w-0`,children:[a(n,{as:`h3`,className:`text-[16px] font-semibold leading-[24px] text-text1 line-clamp-1`,children:u.title}),u.desc&&a(n,{as:`p`,className:`mt-[4px] text-[13px] leading-[20px] text-text2 line-clamp-1`,children:u.desc})]}),a(n,{className:`shrink-0 rounded-[20px] border border-[#FD4C5E] px-[24px] py-[8px] text-[14px] font-normal text-[#FD4C5E]`,children:`观看`})]})]})},u.id||u.title)})}):null}export{u as LargeGridItemClient};
@@ -1,12 +1,15 @@
1
1
 
2
- import { LargeFeatureGridInspectorProps } from "./schema.mjs";
2
+ import { BaseComponentProps } from "../../utils/types/component.mjs";
3
+ import "../../utils/index.mjs";
4
+ import { LargeGridData } from "./types.mjs";
3
5
  import * as react_jsx_runtime0 from "react/jsx-runtime";
4
6
 
5
7
  //#region components/biz/business/large-feature-grid/client.d.ts
6
- type LargeFeatureGridClientProps = LargeFeatureGridInspectorProps;
7
8
  /**
8
- * 大图推荐客户端组件,仅做占位展示,无交互逻辑。
9
+ * 大图推荐客户端组件。
9
10
  */
10
- declare function LargeFeatureGridClient(_props: LargeFeatureGridClientProps): react_jsx_runtime0.JSX.Element;
11
+ declare function LargeFeatureGridClient({
12
+ data
13
+ }: BaseComponentProps<LargeGridData[]>): react_jsx_runtime0.JSX.Element | null;
11
14
  //#endregion
12
- export { LargeFeatureGridClient, LargeFeatureGridClientProps };
15
+ export { LargeFeatureGridClient };
@@ -1,2 +1,2 @@
1
1
 
2
- "use client";import{cn as e}from"../../../../utils/cn.mjs";import{Box as t}from"../../../ui/box.mjs";import{Text as n}from"../../../ui/text.mjs";import{jsx as r,jsxs as i}from"react/jsx-runtime";const a=Array.from({length:4},(e,t)=>({id:t+1,title:`大图推荐 ${t+1}`}));function o(o){return i(t,{as:`section`,className:e(`flex flex-col gap-3 p-4`),"aria-label":`大图推荐`,children:[r(n,{as:`h3`,className:`text-sm font-semibold text-foreground`,children:`大图推荐`}),r(t,{className:`grid grid-cols-2 gap-3`,children:a.map(a=>i(t,{className:e(`flex flex-col overflow-hidden rounded-lg`,`bg-muted/40`),children:[r(t,{className:e(`h-44 w-full`,`bg-gradient-to-br from-muted to-background`),"aria-hidden":!0}),r(n,{as:`span`,className:`px-3 py-2 text-xs text-muted-foreground`,children:a.title})]},a.id))})]})}export{o as LargeFeatureGridClient};
2
+ "use client";import{Box as e}from"../../../ui/box.mjs";import{Text as t}from"../../../ui/text.mjs";import n from"../../../../assets/icons/common/right_arrow.mjs";import r from"../../../ui/link.mjs";import{LargeGridItemClient as i}from"./card-item.mjs";import{mockData as a}from"./mock.mjs";import{jsx as o,jsxs as s}from"react/jsx-runtime";const c=[];function l({data:l=c}){let u=l.length>0?l:a;if(!u||u.length===0)return null;let d=u[0],f=d?.title,p=d?.moreUrl;return s(e,{className:`p-3`,children:[s(e,{className:`flex items-center justify-between mb-[10px] h-[24px]`,children:[f&&o(t,{as:`h2`,className:`text-[18px] font-bold text-text1 line-clamp-1 flex-1 min-w-0 mr-[12px]`,children:f}),p&&s(r,{href:p,className:`flex items-center text-[14px] text-text2 ml-auto`,children:[`更多`,o(n,{className:`ml-[2px] h-[12px] w-[12px] text-text2`})]})]}),u.map((t,n)=>{let{items:r}=t;return r?o(e,{className:n>0?`mt-3`:``,children:o(i,{data:r})},`large-feature-grid-items-${n}`):null})]})}export{l as LargeFeatureGridClient};
@@ -0,0 +1,2 @@
1
+
2
+ const e=[{title:`推荐位名称`,moreUrl:`/channel`,items:{id:`22edc8693ebbdaf1`,cover:`https://base-resources.guadd.fun/md-204/dcc-file/f7/f70a9f9f0c17aa9aff6c3a3e03a822db-small.jpg`,tag:`独家`,playCount:1205,duration:3665,title:`穷小伙一睁眼穿越古代,娶个老婆就能得到奖励,后宫3000宠都宠不过来!谁料女帝主动送上门来,征服女帝可以直接开终极宝箱,不用选择全都可以!`,desc:`穷小伙一睁眼穿越古代,娶个老婆就能得到奖励,后宫3000宠都宠不过来!谁料女帝主动送上门来,征服女帝可以直接开终极宝箱,不用选择全都可以!`}},{items:{id:`242686c512b41c98`,cover:`https://base-resources.guadd.fun/md-204/dcc-file/2c/2cd615a5e471d2bc8a9ccd95038c9067.jpg`,tag:`独家`,playCount:1205,duration:3665,title:`老神医都治不好老爷子的绝症,美女总裁路边随便拉来的穷小伙竟一针救活,老爷子醒后直接把女总裁嫁他,九世的有缘无分换来今世的相守终生`,desc:`老神医都治不好老爷子的绝症,美女总裁路边随便拉来的穷小伙竟一针救活,老爷子醒后直接把女总裁嫁他,九世的有缘无分换来今世的相守终生`}}];export{e as mockData};
@@ -1,11 +1,13 @@
1
1
 
2
- import { LargeFeatureGridClientProps } from "./client.mjs";
2
+ import { BaseComponentProps } from "../../utils/types/component.mjs";
3
+ import "../../utils/index.mjs";
4
+ import { LargeGridData } from "./types.mjs";
3
5
  import * as react_jsx_runtime0 from "react/jsx-runtime";
4
6
 
5
7
  //#region components/biz/business/large-feature-grid/server.d.ts
6
8
  /**
7
9
  * 大图推荐服务端组件,直接渲染客户端组件。
8
10
  */
9
- declare function LargeFeatureGrid(props: LargeFeatureGridClientProps): react_jsx_runtime0.JSX.Element;
11
+ declare function LargeFeatureGrid(props: BaseComponentProps<LargeGridData[]>): react_jsx_runtime0.JSX.Element;
10
12
  //#endregion
11
13
  export { LargeFeatureGrid };
@@ -0,0 +1,33 @@
1
+
2
+ //#region components/biz/business/large-feature-grid/types.d.ts
3
+ /**
4
+ * LargeFeatureGrid 组件类型定义
5
+ */
6
+ interface LargeGridItem {
7
+ /** 内容ID */
8
+ id: string;
9
+ /** 封面图 URL */
10
+ cover: string;
11
+ /** 自定义角标文字 */
12
+ tag?: string;
13
+ /** 角标枚举 */
14
+ superscript?: 0 | 1 | 2;
15
+ /** 播放量 */
16
+ playCount?: string | number;
17
+ /** 视频时长或剧集数 */
18
+ duration?: string | number;
19
+ /** 内容标题 */
20
+ title: string;
21
+ /** 内容描述 */
22
+ desc?: string;
23
+ }
24
+ interface LargeGridData {
25
+ /** 推荐位名称 */
26
+ title?: string;
27
+ /** 更多链接地址 */
28
+ moreUrl?: string;
29
+ /** 卡片内容 */
30
+ items?: LargeGridItem;
31
+ }
32
+ //#endregion
33
+ export { LargeGridData };
@@ -15,7 +15,7 @@ declare const marqueeMaterial: DefineMaterialOption<typeof MarqueeServer, typeof
15
15
  contents: zod.ZodArray<zod.ZodObject<{
16
16
  text: zod.ZodString & SchemaHasDefaultValue;
17
17
  enableClick: zod.ZodBoolean & SchemaHasDefaultValue;
18
- linkType: zod.ZodType<"content" | "url" | "content-list", unknown, zod_v4_core0.$ZodTypeInternals<"content" | "url" | "content-list", unknown>> & SchemaHasDefaultValue;
18
+ linkType: zod.ZodType<"content" | "content-list" | "url", unknown, zod_v4_core0.$ZodTypeInternals<"content" | "content-list" | "url", unknown>> & SchemaHasDefaultValue;
19
19
  link: zod.ZodOptional<zod.ZodString> & SchemaHasDefaultValue;
20
20
  }, zod_v4_core0.$strip>> & SchemaHasDefaultValue;
21
21
  showClose: zod.ZodBoolean & SchemaHasDefaultValue;
@@ -11,7 +11,7 @@ declare const marqueeInspectorPropsSchema: z$1.ZodObject<{
11
11
  contents: z$1.ZodArray<z$1.ZodObject<{
12
12
  text: z$1.ZodString & SchemaHasDefaultValue;
13
13
  enableClick: z$1.ZodBoolean & SchemaHasDefaultValue;
14
- linkType: z$1.ZodType<"content" | "url" | "content-list", unknown, z$1.core.$ZodTypeInternals<"content" | "url" | "content-list", unknown>> & SchemaHasDefaultValue;
14
+ linkType: z$1.ZodType<"content" | "content-list" | "url", unknown, z$1.core.$ZodTypeInternals<"content" | "content-list" | "url", unknown>> & SchemaHasDefaultValue;
15
15
  link: z$1.ZodOptional<z$1.ZodString> & SchemaHasDefaultValue;
16
16
  }, z$1.core.$strip>> & SchemaHasDefaultValue;
17
17
  showClose: z$1.ZodBoolean & SchemaHasDefaultValue;
@@ -23,7 +23,7 @@ declare const marqueeInspectorDefaultProps: {
23
23
  contents: {
24
24
  text: string;
25
25
  enableClick: boolean;
26
- linkType: "content" | "url" | "content-list";
26
+ linkType: "content" | "content-list" | "url";
27
27
  link?: string | undefined;
28
28
  }[];
29
29
  showClose: boolean;
@@ -8,7 +8,7 @@ import * as class_variance_authority_types0 from "class-variance-authority/types
8
8
  /** buttonVariants 工具定义。 */
9
9
  declare const buttonVariants: (props?: ({
10
10
  variant?: "link" | "default" | "destructive" | "secondary" | "outline" | "ghost" | null | undefined;
11
- size?: "default" | "xs" | "sm" | "lg" | "icon" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
11
+ size?: "default" | "icon" | "xs" | "sm" | "lg" | "icon-xs" | "icon-sm" | "icon-lg" | null | undefined;
12
12
  } & class_variance_authority_types0.ClassProp) | undefined) => string;
13
13
  /** Button 组件属性。 */
14
14
  type ButtonProps = Button.Props & VariantProps<typeof buttonVariants> & {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@funhub/platform",
3
3
  "type": "module",
4
- "version": "0.1.29",
4
+ "version": "0.1.31",
5
5
  "private": false,
6
6
  "sideEffects": [
7
7
  "**/*.css"
@@ -1,14 +0,0 @@
1
-
2
- import { InferSchemaProps } from "../../../../utils/schema/schema.mjs";
3
- import "../../../../utils/schema/index.mjs";
4
- import * as zod from "zod";
5
- import * as zod_v4_core0 from "zod/v4/core";
6
-
7
- //#region components/biz/business/large-feature-grid/schema.d.ts
8
- /**
9
- * 大图推荐物料暂不对外开放配置,仅用于占位展示。
10
- */
11
- declare const largeFeatureGridInspectorPropsSchema: zod.ZodObject<{}, zod_v4_core0.$strip>;
12
- type LargeFeatureGridInspectorProps = InferSchemaProps<typeof largeFeatureGridInspectorPropsSchema>;
13
- //#endregion
14
- export { LargeFeatureGridInspectorProps };