diff --git a/packages/components/CHANGELOG.md b/packages/components/CHANGELOG.md index 2fcb7b79..5c42b3a5 100644 --- a/packages/components/CHANGELOG.md +++ b/packages/components/CHANGELOG.md @@ -1,5 +1,14 @@ # @baseapp-frontend/components +## 0.0.41 + +### Patch Changes + +- Added FollowToggle button +- Moved BlockButtonWithDialog, ProfileComponent and related queries and mutations from baseapp-frontend-template +- Updated dependencies + - @baseapp-frontend/design-system@0.0.27 + ## 0.0.40 ### Patch Changes @@ -46,6 +55,7 @@ - Updated dependencies - @baseapp-frontend/graphql@1.1.14 + ## 0.0.34 ### Patch Changes diff --git a/packages/components/__generated__/BlockToggleFragment.graphql.ts b/packages/components/__generated__/BlockToggleFragment.graphql.ts new file mode 100644 index 00000000..6933ec0e --- /dev/null +++ b/packages/components/__generated__/BlockToggleFragment.graphql.ts @@ -0,0 +1,66 @@ +/** + * @generated SignedSource<<736dea7090465a624ce8a92c4ec975ae>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ + +/* eslint-disable */ +// @ts-nocheck +import { Fragment, ReaderFragment } from 'relay-runtime' +import { FragmentRefs } from 'relay-runtime' + +export type BlockToggleFragment$data = { + readonly id: string + readonly isBlockedByMe: boolean | null | undefined + readonly name?: string | null | undefined + readonly ' $fragmentType': 'BlockToggleFragment' +} +export type BlockToggleFragment$key = { + readonly ' $data'?: BlockToggleFragment$data + readonly ' $fragmentSpreads': FragmentRefs<'BlockToggleFragment'> +} + +const node: ReaderFragment = { + argumentDefinitions: [], + kind: 'Fragment', + metadata: null, + name: 'BlockToggleFragment', + selections: [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'id', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'isBlockedByMe', + storageKey: null, + }, + { + kind: 'InlineFragment', + selections: [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'name', + storageKey: null, + }, + ], + type: 'Profile', + abstractKey: null, + }, + ], + type: 'BlocksInterface', + abstractKey: '__isBlocksInterface', +} + +;(node as any).hash = 'e03ed2e064ae6dbdca724087c1dfdd16' + +export default node diff --git a/packages/components/__generated__/BlockToggleMutation.graphql.ts b/packages/components/__generated__/BlockToggleMutation.graphql.ts new file mode 100644 index 00000000..701e71a7 --- /dev/null +++ b/packages/components/__generated__/BlockToggleMutation.graphql.ts @@ -0,0 +1,234 @@ +/** + * @generated SignedSource<<67a5f0e7cdc45cc2315b67143872610e>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ + +/* eslint-disable */ +// @ts-nocheck +import { ConcreteRequest, Mutation } from 'relay-runtime' +import { FragmentRefs } from 'relay-runtime' + +export type BlockToggleInput = { + actorObjectId: string + clientMutationId?: string | null | undefined + targetObjectId: string +} +export type BlockToggleMutation$variables = { + input: BlockToggleInput +} +export type BlockToggleMutation$data = { + readonly blockToggle: + | { + readonly block: + | { + readonly node: + | { + readonly id: string + } + | null + | undefined + } + | null + | undefined + readonly blockDeletedId: string | null | undefined + readonly target: + | { + readonly id: string + readonly isBlockedByMe: boolean | null | undefined + readonly ' $fragmentSpreads': FragmentRefs<'BlockToggleFragment'> + } + | null + | undefined + } + | null + | undefined +} +export type BlockToggleMutation = { + response: BlockToggleMutation$data + variables: BlockToggleMutation$variables +} + +const node: ConcreteRequest = (function () { + var v0 = [ + { + defaultValue: null, + kind: 'LocalArgument', + name: 'input', + }, + ], + v1 = [ + { + kind: 'Variable', + name: 'input', + variableName: 'input', + }, + ], + v2 = { + alias: null, + args: null, + kind: 'ScalarField', + name: 'id', + storageKey: null, + }, + v3 = { + alias: null, + args: null, + concreteType: 'BlockEdge', + kind: 'LinkedField', + name: 'block', + plural: false, + selections: [ + { + alias: null, + args: null, + concreteType: 'Block', + kind: 'LinkedField', + name: 'node', + plural: false, + selections: [v2 /*: any*/], + storageKey: null, + }, + ], + storageKey: null, + }, + v4 = { + alias: null, + args: null, + kind: 'ScalarField', + name: 'blockDeletedId', + storageKey: null, + }, + v5 = { + alias: null, + args: null, + kind: 'ScalarField', + name: 'isBlockedByMe', + storageKey: null, + } + return { + fragment: { + argumentDefinitions: v0 /*: any*/, + kind: 'Fragment', + metadata: null, + name: 'BlockToggleMutation', + selections: [ + { + alias: null, + args: v1 /*: any*/, + concreteType: 'BlockTogglePayload', + kind: 'LinkedField', + name: 'blockToggle', + plural: false, + selections: [ + v3 /*: any*/, + v4 /*: any*/, + { + alias: null, + args: null, + concreteType: null, + kind: 'LinkedField', + name: 'target', + plural: false, + selections: [ + v2 /*: any*/, + v5 /*: any*/, + { + args: null, + kind: 'FragmentSpread', + name: 'BlockToggleFragment', + }, + ], + storageKey: null, + }, + ], + storageKey: null, + }, + ], + type: 'Mutation', + abstractKey: null, + }, + kind: 'Request', + operation: { + argumentDefinitions: v0 /*: any*/, + kind: 'Operation', + name: 'BlockToggleMutation', + selections: [ + { + alias: null, + args: v1 /*: any*/, + concreteType: 'BlockTogglePayload', + kind: 'LinkedField', + name: 'blockToggle', + plural: false, + selections: [ + v3 /*: any*/, + v4 /*: any*/, + { + alias: null, + args: null, + filters: null, + handle: 'deleteRecord', + key: '', + kind: 'ScalarHandle', + name: 'blockDeletedId', + }, + { + alias: null, + args: null, + concreteType: null, + kind: 'LinkedField', + name: 'target', + plural: false, + selections: [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: '__typename', + storageKey: null, + }, + v2 /*: any*/, + v5 /*: any*/, + { + kind: 'TypeDiscriminator', + abstractKey: '__isBlocksInterface', + }, + { + kind: 'InlineFragment', + selections: [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'name', + storageKey: null, + }, + ], + type: 'Profile', + abstractKey: null, + }, + ], + storageKey: null, + }, + ], + storageKey: null, + }, + ], + }, + params: { + cacheID: 'ffed8bf057da30f64200e9f801d9186c', + id: null, + metadata: {}, + name: 'BlockToggleMutation', + operationKind: 'mutation', + text: 'mutation BlockToggleMutation(\n $input: BlockToggleInput!\n) {\n blockToggle(input: $input) {\n block {\n node {\n id\n }\n }\n blockDeletedId\n target {\n __typename\n id\n isBlockedByMe\n ...BlockToggleFragment\n }\n }\n}\n\nfragment BlockToggleFragment on BlocksInterface {\n __isBlocksInterface: __typename\n id\n isBlockedByMe\n ... on Profile {\n id\n name\n }\n}\n', + }, + } +})() + +;(node as any).hash = '065f29d79d6f508cd4db5788802958e5' + +export default node diff --git a/packages/components/__generated__/FollowToggleMutation.graphql.ts b/packages/components/__generated__/FollowToggleMutation.graphql.ts new file mode 100644 index 00000000..18f528bf --- /dev/null +++ b/packages/components/__generated__/FollowToggleMutation.graphql.ts @@ -0,0 +1,223 @@ +/** + * @generated SignedSource<<8262681c5d1a1ba5f85d82327c6d6cbc>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ + +/* eslint-disable */ +// @ts-nocheck +import { ConcreteRequest, Mutation } from 'relay-runtime' +import { FragmentRefs } from 'relay-runtime' + +export type FollowToggleInput = { + actorObjectId: string + clientMutationId?: string | null | undefined + targetObjectId: string +} +export type FollowToggleMutation$variables = { + input: FollowToggleInput +} +export type FollowToggleMutation$data = { + readonly followToggle: + | { + readonly follow: + | { + readonly node: + | { + readonly target: { + readonly $updatableFragmentSpreads: FragmentRefs<'FollowToggleUpdatableFragment'> + readonly followersCount: number | null | undefined + readonly isFollowedByMe: boolean | null | undefined + } + } + | null + | undefined + } + | null + | undefined + } + | null + | undefined +} +export type FollowToggleMutation = { + response: FollowToggleMutation$data + variables: FollowToggleMutation$variables +} + +const node: ConcreteRequest = (function () { + var v0 = [ + { + defaultValue: null, + kind: 'LocalArgument', + name: 'input', + }, + ], + v1 = [ + { + kind: 'Variable', + name: 'input', + variableName: 'input', + }, + ], + v2 = { + alias: null, + args: null, + kind: 'ScalarField', + name: 'isFollowedByMe', + storageKey: null, + }, + v3 = { + alias: null, + args: null, + kind: 'ScalarField', + name: 'followersCount', + storageKey: null, + }, + v4 = { + alias: null, + args: null, + kind: 'ScalarField', + name: 'id', + storageKey: null, + } + return { + fragment: { + argumentDefinitions: v0 /*: any*/, + kind: 'Fragment', + metadata: null, + name: 'FollowToggleMutation', + selections: [ + { + alias: null, + args: v1 /*: any*/, + concreteType: 'FollowTogglePayload', + kind: 'LinkedField', + name: 'followToggle', + plural: false, + selections: [ + { + alias: null, + args: null, + concreteType: 'FollowEdge', + kind: 'LinkedField', + name: 'follow', + plural: false, + selections: [ + { + alias: null, + args: null, + concreteType: 'Follow', + kind: 'LinkedField', + name: 'node', + plural: false, + selections: [ + { + alias: null, + args: null, + concreteType: 'Profile', + kind: 'LinkedField', + name: 'target', + plural: false, + selections: [ + v2 /*: any*/, + v3 /*: any*/, + { + args: null, + kind: 'FragmentSpread', + name: 'FollowToggleUpdatableFragment', + }, + ], + storageKey: null, + }, + ], + storageKey: null, + }, + ], + storageKey: null, + }, + ], + storageKey: null, + }, + ], + type: 'Mutation', + abstractKey: null, + }, + kind: 'Request', + operation: { + argumentDefinitions: v0 /*: any*/, + kind: 'Operation', + name: 'FollowToggleMutation', + selections: [ + { + alias: null, + args: v1 /*: any*/, + concreteType: 'FollowTogglePayload', + kind: 'LinkedField', + name: 'followToggle', + plural: false, + selections: [ + { + alias: null, + args: null, + concreteType: 'FollowEdge', + kind: 'LinkedField', + name: 'follow', + plural: false, + selections: [ + { + alias: null, + args: null, + concreteType: 'Follow', + kind: 'LinkedField', + name: 'node', + plural: false, + selections: [ + { + alias: null, + args: null, + concreteType: 'Profile', + kind: 'LinkedField', + name: 'target', + plural: false, + selections: [ + v2 /*: any*/, + v3 /*: any*/, + { + alias: null, + args: null, + kind: 'ScalarField', + name: '__typename', + storageKey: null, + }, + v4 /*: any*/, + ], + storageKey: null, + }, + v4 /*: any*/, + ], + storageKey: null, + }, + ], + storageKey: null, + }, + ], + storageKey: null, + }, + ], + }, + params: { + cacheID: 'ebebfbcba39ec99da7c9589554a460d5', + id: null, + metadata: {}, + name: 'FollowToggleMutation', + operationKind: 'mutation', + text: 'mutation FollowToggleMutation(\n $input: FollowToggleInput!\n) {\n followToggle(input: $input) {\n follow {\n node {\n target {\n isFollowedByMe\n followersCount\n __typename\n id\n }\n id\n }\n }\n }\n}\n', + }, + } +})() + +;(node as any).hash = 'd58a9c2e3572d54fec982030e1ccaab0' + +export default node diff --git a/packages/components/__generated__/FollowToggleUpdatableFragment.graphql.ts b/packages/components/__generated__/FollowToggleUpdatableFragment.graphql.ts new file mode 100644 index 00000000..0860759f --- /dev/null +++ b/packages/components/__generated__/FollowToggleUpdatableFragment.graphql.ts @@ -0,0 +1,51 @@ +/** + * @generated SignedSource<<0c7af4c419997e9ef8ef7bf922938d7c>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ + +/* eslint-disable */ +// @ts-nocheck +import { ReaderFragment, UpdatableFragment } from 'relay-runtime' +import { FragmentRefs } from 'relay-runtime' + +export type FollowToggleUpdatableFragment$data = { + followersCount: number | null | undefined + isFollowedByMe: boolean | null | undefined + readonly ' $fragmentType': 'FollowToggleUpdatableFragment' +} +export type FollowToggleUpdatableFragment$key = { + readonly ' $data'?: FollowToggleUpdatableFragment$data + readonly $updatableFragmentSpreads: FragmentRefs<'FollowToggleUpdatableFragment'> +} + +const node: ReaderFragment = { + argumentDefinitions: [], + kind: 'Fragment', + metadata: null, + name: 'FollowToggleUpdatableFragment', + selections: [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'isFollowedByMe', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'followersCount', + storageKey: null, + }, + ], + type: 'Profile', + abstractKey: null, +} + +;(node as any).hash = '4d151f5906c7d00fa429a6ccd27ca8bd' + +export default node diff --git a/packages/components/__generated__/ProfileComponentFragment.graphql.ts b/packages/components/__generated__/ProfileComponentFragment.graphql.ts new file mode 100644 index 00000000..63f366f5 --- /dev/null +++ b/packages/components/__generated__/ProfileComponentFragment.graphql.ts @@ -0,0 +1,231 @@ +/** + * @generated SignedSource<> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ + +/* eslint-disable */ +// @ts-nocheck +import { Fragment, ReaderFragment } from 'relay-runtime' +import { FragmentRefs } from 'relay-runtime' + +export type ProfilesProfileStatusChoices = 'A_1' | 'A_2' | '%future added value' + +export type ProfileComponentFragment$data = { + readonly bannerImage: + | { + readonly url: string + } + | null + | undefined + readonly biography: string | null | undefined + readonly canChange: boolean | null | undefined + readonly followersCount: number | null | undefined + readonly followingCount: number | null | undefined + readonly id: string + readonly image: + | { + readonly url: string + } + | null + | undefined + readonly isBlockedByMe: boolean | null | undefined + readonly isFollowedByMe: boolean | null | undefined + readonly name: string | null | undefined + readonly owner: { + readonly phoneNumber: string | null | undefined + } + readonly status: ProfilesProfileStatusChoices + readonly urlPath: + | { + readonly path: string + } + | null + | undefined + readonly ' $fragmentSpreads': FragmentRefs<'BlockToggleFragment'> + readonly ' $fragmentType': 'ProfileComponentFragment' +} +export type ProfileComponentFragment$key = { + readonly ' $data'?: ProfileComponentFragment$data + readonly ' $fragmentSpreads': FragmentRefs<'ProfileComponentFragment'> +} + +const node: ReaderFragment = (function () { + var v0 = [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'url', + storageKey: null, + }, + ] + return { + argumentDefinitions: [], + kind: 'Fragment', + metadata: null, + name: 'ProfileComponentFragment', + selections: [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'id', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'status', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'name', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'biography', + storageKey: null, + }, + { + alias: null, + args: [ + { + kind: 'Literal', + name: 'height', + value: 96, + }, + { + kind: 'Literal', + name: 'width', + value: 96, + }, + ], + concreteType: 'File', + kind: 'LinkedField', + name: 'image', + plural: false, + selections: v0 /*: any*/, + storageKey: 'image(height:96,width:96)', + }, + { + alias: null, + args: [ + { + kind: 'Literal', + name: 'height', + value: 290, + }, + { + kind: 'Literal', + name: 'width', + value: 868, + }, + ], + concreteType: 'File', + kind: 'LinkedField', + name: 'bannerImage', + plural: false, + selections: v0 /*: any*/, + storageKey: 'bannerImage(height:290,width:868)', + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'isFollowedByMe', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'followersCount', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'followingCount', + storageKey: null, + }, + { + alias: 'canChange', + args: [ + { + kind: 'Literal', + name: 'perm', + value: 'change', + }, + ], + kind: 'ScalarField', + name: 'hasPerm', + storageKey: 'hasPerm(perm:"change")', + }, + { + alias: null, + args: null, + concreteType: 'URLPath', + kind: 'LinkedField', + name: 'urlPath', + plural: false, + selections: [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'path', + storageKey: null, + }, + ], + storageKey: null, + }, + { + alias: null, + args: null, + concreteType: 'User', + kind: 'LinkedField', + name: 'owner', + plural: false, + selections: [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'phoneNumber', + storageKey: null, + }, + ], + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'isBlockedByMe', + storageKey: null, + }, + { + args: null, + kind: 'FragmentSpread', + name: 'BlockToggleFragment', + }, + ], + type: 'Profile', + abstractKey: null, + } +})() + +;(node as any).hash = '14c553f27fa01a11431eb14bb57b92c8' + +export default node diff --git a/packages/components/__generated__/ProfileUpdateMutation.graphql.ts b/packages/components/__generated__/ProfileUpdateMutation.graphql.ts new file mode 100644 index 00000000..5fa7fbd6 --- /dev/null +++ b/packages/components/__generated__/ProfileUpdateMutation.graphql.ts @@ -0,0 +1,343 @@ +/** + * @generated SignedSource<<836b5baa0a9d93ecb928d3531107a238>> + * @lightSyntaxTransform + * @nogrep + */ + +/* tslint:disable */ + +/* eslint-disable */ +// @ts-nocheck +import { ConcreteRequest, Mutation } from 'relay-runtime' +import { FragmentRefs } from 'relay-runtime' + +export type ProfileUpdateInput = { + bannerImage?: string | null | undefined + biography?: string | null | undefined + clientMutationId?: string | null | undefined + id: string + image?: string | null | undefined + name?: string | null | undefined + owner?: string | null | undefined + phoneNumber?: string | null | undefined + urlPath?: string | null | undefined +} +export type ProfileUpdateMutation$variables = { + input: ProfileUpdateInput +} +export type ProfileUpdateMutation$data = { + readonly profileUpdate: + | { + readonly errors: + | ReadonlyArray< + | { + readonly field: string + readonly messages: ReadonlyArray + } + | null + | undefined + > + | null + | undefined + readonly profile: + | { + readonly ' $fragmentSpreads': FragmentRefs<'ProfileComponentFragment'> + } + | null + | undefined + } + | null + | undefined +} +export type ProfileUpdateMutation = { + response: ProfileUpdateMutation$data + variables: ProfileUpdateMutation$variables +} + +const node: ConcreteRequest = (function () { + var v0 = [ + { + defaultValue: null, + kind: 'LocalArgument', + name: 'input', + }, + ], + v1 = [ + { + kind: 'Variable', + name: 'input', + variableName: 'input', + }, + ], + v2 = { + alias: null, + args: null, + concreteType: 'ErrorType', + kind: 'LinkedField', + name: 'errors', + plural: true, + selections: [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'field', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'messages', + storageKey: null, + }, + ], + storageKey: null, + }, + v3 = { + alias: null, + args: null, + kind: 'ScalarField', + name: 'id', + storageKey: null, + }, + v4 = [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'url', + storageKey: null, + }, + ] + return { + fragment: { + argumentDefinitions: v0 /*: any*/, + kind: 'Fragment', + metadata: null, + name: 'ProfileUpdateMutation', + selections: [ + { + alias: null, + args: v1 /*: any*/, + concreteType: 'ProfileUpdatePayload', + kind: 'LinkedField', + name: 'profileUpdate', + plural: false, + selections: [ + { + alias: null, + args: null, + concreteType: 'Profile', + kind: 'LinkedField', + name: 'profile', + plural: false, + selections: [ + { + args: null, + kind: 'FragmentSpread', + name: 'ProfileComponentFragment', + }, + ], + storageKey: null, + }, + v2 /*: any*/, + ], + storageKey: null, + }, + ], + type: 'Mutation', + abstractKey: null, + }, + kind: 'Request', + operation: { + argumentDefinitions: v0 /*: any*/, + kind: 'Operation', + name: 'ProfileUpdateMutation', + selections: [ + { + alias: null, + args: v1 /*: any*/, + concreteType: 'ProfileUpdatePayload', + kind: 'LinkedField', + name: 'profileUpdate', + plural: false, + selections: [ + { + alias: null, + args: null, + concreteType: 'Profile', + kind: 'LinkedField', + name: 'profile', + plural: false, + selections: [ + v3 /*: any*/, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'status', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'name', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'biography', + storageKey: null, + }, + { + alias: null, + args: [ + { + kind: 'Literal', + name: 'height', + value: 96, + }, + { + kind: 'Literal', + name: 'width', + value: 96, + }, + ], + concreteType: 'File', + kind: 'LinkedField', + name: 'image', + plural: false, + selections: v4 /*: any*/, + storageKey: 'image(height:96,width:96)', + }, + { + alias: null, + args: [ + { + kind: 'Literal', + name: 'height', + value: 290, + }, + { + kind: 'Literal', + name: 'width', + value: 868, + }, + ], + concreteType: 'File', + kind: 'LinkedField', + name: 'bannerImage', + plural: false, + selections: v4 /*: any*/, + storageKey: 'bannerImage(height:290,width:868)', + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'isFollowedByMe', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'followersCount', + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'followingCount', + storageKey: null, + }, + { + alias: 'canChange', + args: [ + { + kind: 'Literal', + name: 'perm', + value: 'change', + }, + ], + kind: 'ScalarField', + name: 'hasPerm', + storageKey: 'hasPerm(perm:"change")', + }, + { + alias: null, + args: null, + concreteType: 'URLPath', + kind: 'LinkedField', + name: 'urlPath', + plural: false, + selections: [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'path', + storageKey: null, + }, + v3 /*: any*/, + ], + storageKey: null, + }, + { + alias: null, + args: null, + concreteType: 'User', + kind: 'LinkedField', + name: 'owner', + plural: false, + selections: [ + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'phoneNumber', + storageKey: null, + }, + v3 /*: any*/, + ], + storageKey: null, + }, + { + alias: null, + args: null, + kind: 'ScalarField', + name: 'isBlockedByMe', + storageKey: null, + }, + { + kind: 'TypeDiscriminator', + abstractKey: '__isBlocksInterface', + }, + ], + storageKey: null, + }, + v2 /*: any*/, + ], + storageKey: null, + }, + ], + }, + params: { + cacheID: 'c0e960cbeeab17c8f65cbae625436ab9', + id: null, + metadata: {}, + name: 'ProfileUpdateMutation', + operationKind: 'mutation', + text: 'mutation ProfileUpdateMutation(\n $input: ProfileUpdateInput!\n) {\n profileUpdate(input: $input) {\n profile {\n ...ProfileComponentFragment\n id\n }\n errors {\n field\n messages\n }\n }\n}\n\nfragment BlockToggleFragment on BlocksInterface {\n __isBlocksInterface: __typename\n id\n isBlockedByMe\n ... on Profile {\n id\n name\n }\n}\n\nfragment ProfileComponentFragment on Profile {\n id\n status\n name\n biography\n image(height: 96, width: 96) {\n url\n }\n bannerImage(height: 290, width: 868) {\n url\n }\n isFollowedByMe\n followersCount\n followingCount\n canChange: hasPerm(perm: "change")\n urlPath {\n path\n id\n }\n owner {\n phoneNumber\n id\n }\n isBlockedByMe\n ...BlockToggleFragment\n}\n', + }, + } +})() + +;(node as any).hash = 'b15251b426798b8c3457aed1249f8a64' + +export default node diff --git a/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/constants.ts b/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/constants.ts new file mode 100644 index 00000000..e88a5d73 --- /dev/null +++ b/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/constants.ts @@ -0,0 +1,14 @@ +export const BLOCK_UNBLOCK_DIALOG_TEXTS = { + block: { + title: 'Block', + content: + "This person won’t be able to send you messages, find your profile or content. They won’t see your comments and reactions, and won't be able to mention or follow your profile. We won't notify them that they have been blocked.", + action: 'Block', + }, + unblock: { + title: 'Unblock', + content: + "This person will be able to send you messages, find your profile or content. They will see your comments and reactions, and will be able to mention or follow your profile. We won't notify them that they have been unblocked.", + action: 'Unblock', + }, +} diff --git a/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/index.tsx b/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/index.tsx new file mode 100644 index 00000000..e47c2ce2 --- /dev/null +++ b/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/index.tsx @@ -0,0 +1,125 @@ +import { FC, useState } from 'react' + +import { BlockIcon, ConfirmDialog, UnblockIcon } from '@baseapp-frontend/design-system' +import { useNotification } from '@baseapp-frontend/utils' + +import { Button, CircularProgress, Typography } from '@mui/material' +import { useFragment, useMutation } from 'react-relay' + +import { BlockToggleMutation } from '../../../../__generated__/BlockToggleMutation.graphql' +import { BlockToggleMutationQuery } from '../../graphql/mutations/BlockToggle' +import { BlockToggleFragment } from '../../graphql/queries/BlockToggle' +import { BLOCK_UNBLOCK_DIALOG_TEXTS } from './constants' +import { ActionButton } from './styled' +import { BlockButtonWithDialogProps } from './types' + +const BlockButtonWithDialog: FC = ({ + target: targetRef, + isMenu, + handleError, + handleCloseMenu, + currentProfileId, +}) => { + const target = useFragment(BlockToggleFragment, targetRef) + const [commitMutation, isMutationInFlight] = + useMutation(BlockToggleMutationQuery) + const { sendToast } = useNotification() + const [open, setOpen] = useState(false) + + const isBlockedByMe = target?.isBlockedByMe + + const handleOpen = () => { + setOpen(true) + } + + const handleClose = () => { + setOpen(false) + } + + const handleSuccess = () => { + setOpen(false) + handleCloseMenu?.() + } + + const handleBlock = () => { + if (isMutationInFlight || !currentProfileId || !target) { + return + } + + commitMutation({ + variables: { + input: { + targetObjectId: target.id, + actorObjectId: currentProfileId, + }, + }, + onCompleted: (response, errors) => { + errors?.forEach((error) => { + sendToast(error.message, { type: 'error' }) + }) + handleSuccess() + sendToast( + `${target.name ?? ''} is ${response?.blockToggle?.target?.isBlockedByMe ? 'blocked' : 'unblocked'}`, + { type: 'info' }, + ) + }, + onError: () => { + handleError?.() + }, + }) + } + + return ( + <> + + + {isBlockedByMe ? : } + {`${isBlockedByMe ? BLOCK_UNBLOCK_DIALOG_TEXTS.unblock.title : BLOCK_UNBLOCK_DIALOG_TEXTS.block.title} ${target.name}?`} + + } + content={ + isBlockedByMe + ? BLOCK_UNBLOCK_DIALOG_TEXTS.unblock.content + : BLOCK_UNBLOCK_DIALOG_TEXTS.block.content + } + onClose={handleClose} + action={ + + {isBlockedByMe + ? BLOCK_UNBLOCK_DIALOG_TEXTS.unblock.action + : BLOCK_UNBLOCK_DIALOG_TEXTS.block.action} + {isMutationInFlight && } + + } + /> + + ) +} + +export default BlockButtonWithDialog diff --git a/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/styled.tsx b/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/styled.tsx new file mode 100644 index 00000000..61c8241f --- /dev/null +++ b/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/styled.tsx @@ -0,0 +1,11 @@ +import { Button } from '@mui/material' +import { styled } from '@mui/material/styles' + +import { ActionButtonProps } from './types' + +export const ActionButton = styled(Button)(({ theme, isBlocked = false }) => ({ + backgroundColor: isBlocked ? theme.palette.grey[800] : theme.palette.error.main, + '&:hover': { + backgroundColor: isBlocked ? theme.palette.grey[900] : theme.palette.error.dark, + }, +})) diff --git a/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/types.ts b/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/types.ts new file mode 100644 index 00000000..2237df49 --- /dev/null +++ b/packages/components/modules/profiles/ProfileComponent/BlockButtonWithDialog/types.ts @@ -0,0 +1,15 @@ +import { ButtonProps } from '@mui/material' + +import { BlockToggleFragment$key } from '../../../../__generated__/BlockToggleFragment.graphql' + +export interface ActionButtonProps extends ButtonProps { + isBlocked?: boolean | null +} + +export interface BlockButtonWithDialogProps { + target: BlockToggleFragment$key + currentProfileId?: string + isMenu?: boolean + handleError?: () => void + handleCloseMenu?: () => void +} diff --git a/packages/components/modules/profiles/ProfileComponent/FollowToggleButton/index.tsx b/packages/components/modules/profiles/ProfileComponent/FollowToggleButton/index.tsx new file mode 100644 index 00000000..1775904c --- /dev/null +++ b/packages/components/modules/profiles/ProfileComponent/FollowToggleButton/index.tsx @@ -0,0 +1,84 @@ +import { FC } from 'react' + +import { Iconify } from '@baseapp-frontend/design-system' +import { useNotification } from '@baseapp-frontend/utils' + +import { Button } from '@mui/material' +import { useMutation, useRelayEnvironment } from 'react-relay' +import { RecordSourceSelectorProxy, commitLocalUpdate } from 'relay-runtime' + +import { FollowToggleMutation } from '../../../../__generated__/FollowToggleMutation.graphql' +import { FollowToggleMutationQuery } from '../../graphql/mutations/FollowToggle' +import { FollowToggleUpdatableFragment } from '../../graphql/queries/FollowToggleUpdatableFragment' +import { FollowToggleButtonProps } from './types' + +const FollowToggleButton: FC = ({ + targetId, + isFollowedByMe, + currentProfileId, + profileRef, +}) => { + const [commitMutation, isMutationInFlight] = + useMutation(FollowToggleMutationQuery) + const { sendToast } = useNotification() + const environment = useRelayEnvironment() + + const toggleFollow = () => { + if (isMutationInFlight || !currentProfileId || !targetId) { + return + } + + commitMutation({ + variables: { + input: { + targetObjectId: targetId, + actorObjectId: currentProfileId, + }, + }, + onCompleted: (response, errors) => { + errors?.forEach((error) => { + sendToast(error.message, { type: 'error' }) + }) + if (errors) { + return + } + const follow = response.followToggle?.follow + + commitLocalUpdate(environment, (store: RecordSourceSelectorProxy) => { + if (profileRef == null) { + return + } + + const { updatableData } = store.readUpdatableFragment( + FollowToggleUpdatableFragment, + profileRef, + ) + + const updatedIsFollowedByMe = follow?.node?.target?.isFollowedByMe ?? false + const updatedFollowersCount = + follow?.node?.target?.followersCount ?? updatableData.followersCount - 1 + + updatableData.isFollowedByMe = updatedIsFollowedByMe + updatableData.followersCount = updatedFollowersCount + }) + }, + }) + } + + return ( + + ) +} + +export default FollowToggleButton diff --git a/packages/components/modules/profiles/ProfileComponent/FollowToggleButton/types.ts b/packages/components/modules/profiles/ProfileComponent/FollowToggleButton/types.ts new file mode 100644 index 00000000..0cd79e4f --- /dev/null +++ b/packages/components/modules/profiles/ProfileComponent/FollowToggleButton/types.ts @@ -0,0 +1,6 @@ +export interface FollowToggleButtonProps { + targetId?: string + isFollowedByMe: boolean | null | undefined + currentProfileId?: string + profileRef?: any +} diff --git a/packages/components/modules/profiles/ProfileComponent/index.tsx b/packages/components/modules/profiles/ProfileComponent/index.tsx new file mode 100644 index 00000000..4f59260e --- /dev/null +++ b/packages/components/modules/profiles/ProfileComponent/index.tsx @@ -0,0 +1,207 @@ +'use client' + +import { FC, useState } from 'react' + +import { + AvatarWithPlaceholder, + ImageWithFallback, + OutlinedEditIcon, + ShareIcon, + SwipeableDrawer, + ThreeDotsIcon, + useResponsive, +} from '@baseapp-frontend/design-system' +import { useNotification } from '@baseapp-frontend/utils' + +import { Button, MenuItem, Typography } from '@mui/material' +import { useRouter } from 'next/navigation' +import numbro from 'numbro' +import { useFragment } from 'react-relay' + +import { ProfileComponentFragment } from '../graphql/queries/ProfileComponent' +import BlockButtonWithDialog from './BlockButtonWithDialog' +import FollowToggleButton from './FollowToggleButton' +import { + ProfileContainer, + ProfileContentContainer, + ProfileDescriptionContainer, + ProfileNameContainer, + StyledMenu, +} from './styled' +import { ProfileComponentProps } from './types' + +const ProfileComponent: FC = ({ profile: profileRef, currentProfileId }) => { + const profile = useFragment(ProfileComponentFragment, profileRef) + const smDown = useResponsive('down', 'sm') + const router = useRouter() + const [anchorEl, setAnchorEl] = useState(null) + + const open = Boolean(anchorEl) + const handleClick = (event: React.MouseEvent) => { + setAnchorEl(event.currentTarget) + } + const handleClose = () => { + setAnchorEl(null) + } + const { sendToast } = useNotification() + + const handleShareClick = () => { + const path = profile?.urlPath?.path ?? `/profile/${profile?.id}` + const url = [process.env.NEXT_PUBLIC_APP_BASE_URL, path].join('') + navigator.clipboard.writeText(url) + sendToast('Profile URL copied to clipboard!', { type: 'success' }) + handleClose() + } + + const formatFollowCount = (count?: number | null) => { + if (!count || count === 0) { + return 0 + } + if (count <= 1000) { + return count + } + if (count < 1050000) { + return numbro(count).format({ average: true }) + } + return numbro(count).format({ average: true, mantissa: 1 }) + } + + const renderProfileUpdatesButtons = () => { + if (currentProfileId === profile?.id) { + return ( + + ) + } + return ( +
+ {!profile?.isBlockedByMe && ( + + )} + {profile?.isBlockedByMe && ( + + )} +
+ ) + } + + return ( +
+ + + + + + +
+ + {profile?.name} + + + {profile?.urlPath?.path ? `@${profile.urlPath.path}` : ''} + +
+
+
+ + {formatFollowCount(profile?.followersCount)} + + + Followers + +
+
+ + {formatFollowCount(profile?.followingCount)} + + + Following + +
+
+
+

{profile?.biography}

+
+
+ {renderProfileUpdatesButtons()} + + {!smDown && ( + + + + Share profile + + {profile && ( + + )} + + )} + {smDown && ( + + + + Share profile + + {profile && ( + + )} + + )} +
+
+
+
+ ) +} + +export default ProfileComponent diff --git a/packages/components/modules/profiles/ProfileComponent/styled.tsx b/packages/components/modules/profiles/ProfileComponent/styled.tsx new file mode 100644 index 00000000..250bffc6 --- /dev/null +++ b/packages/components/modules/profiles/ProfileComponent/styled.tsx @@ -0,0 +1,84 @@ +import { Box, Menu, MenuProps } from '@mui/material' +import { alpha, styled } from '@mui/material/styles' + +export const ProfileContainer = styled(Box)(({ theme }) => ({ + boxSizing: 'content-box', + display: 'grid', + width: '100%', + height: '100%', + maxWidth: 'fit-content', + gridAutoRows: 'max-content', + gridTemplateColumns: '1fr', + rowGap: theme.spacing(3), + placeSelf: 'center', + padding: `0 ${theme.spacing(2)} ${theme.spacing(2)}`, +})) + +export const ProfileContentContainer = styled(Box)(({ theme }) => ({ + display: 'grid', + gridTemplateColumns: '1fr', + gridTemplateRows: 'min-content auto', + gap: theme.spacing(3), + position: 'relative', + top: -48, + justifyContent: 'center', + [theme.breakpoints.up('sm')]: { + position: 'static', + top: 0, + gridTemplateColumns: 'max-content 480px', + gridTemplateRows: '1fr', + }, +})) + +export const ProfileDescriptionContainer = styled(Box)(({ theme }) => ({ + display: 'grid', + gridTemplateRows: 'auto auto', + gap: theme.spacing(3), + [theme.breakpoints.up('sm')]: { + gap: theme.spacing(2), + }, +})) + +export const ProfileNameContainer = styled(Box)(({ theme }) => ({ + display: 'grid', + gridTemplateRows: 'auto auto', + gridTemplateColumns: '1fr', + rowGap: theme.spacing(3), + placeItems: 'stretch', + justifyItems: 'center', + [theme.breakpoints.up('sm')]: { + gridTemplateRows: 'none', + gridTemplateColumns: '1fr 1fr', + columnGap: theme.spacing(3), + }, +})) + +export const StyledMenu = styled((props: MenuProps) => ( + +))(({ theme }) => ({ + '& .MuiPaper-root': { + minWidth: 190, + '& .MuiMenuItem-root': { + '& .MuiSvgIcon-root': { + marginRight: theme.spacing(1.5), + }, + '&:active': { + backgroundColor: alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity), + }, + }, + ...theme.applyStyles('dark', { + color: theme.palette.grey[300], + }), + }, +})) diff --git a/packages/components/modules/profiles/ProfileComponent/types.ts b/packages/components/modules/profiles/ProfileComponent/types.ts new file mode 100644 index 00000000..ab5c1257 --- /dev/null +++ b/packages/components/modules/profiles/ProfileComponent/types.ts @@ -0,0 +1,6 @@ +import { ProfileComponentFragment$key } from '../../../__generated__/ProfileComponentFragment.graphql' + +export interface ProfileComponentProps { + profile?: ProfileComponentFragment$key | null + currentProfileId?: string +} diff --git a/packages/components/modules/profiles/graphql/mutations/BlockToggle.ts b/packages/components/modules/profiles/graphql/mutations/BlockToggle.ts new file mode 100644 index 00000000..dd90e334 --- /dev/null +++ b/packages/components/modules/profiles/graphql/mutations/BlockToggle.ts @@ -0,0 +1,19 @@ +import { graphql } from 'relay-runtime' + +export const BlockToggleMutationQuery = graphql` + mutation BlockToggleMutation($input: BlockToggleInput!) { + blockToggle(input: $input) { + block { + node { + id + } + } + blockDeletedId @deleteRecord + target { + id + isBlockedByMe + ...BlockToggleFragment + } + } + } +` diff --git a/packages/components/modules/profiles/graphql/mutations/FollowToggle.ts b/packages/components/modules/profiles/graphql/mutations/FollowToggle.ts new file mode 100644 index 00000000..28d9c91d --- /dev/null +++ b/packages/components/modules/profiles/graphql/mutations/FollowToggle.ts @@ -0,0 +1,17 @@ +import { graphql } from 'relay-runtime' + +export const FollowToggleMutationQuery = graphql` + mutation FollowToggleMutation($input: FollowToggleInput!) { + followToggle(input: $input) { + follow { + node { + target { + isFollowedByMe + followersCount + ...FollowToggleUpdatableFragment + } + } + } + } + } +` diff --git a/packages/components/modules/profiles/graphql/mutations/ProfileUpdate.ts b/packages/components/modules/profiles/graphql/mutations/ProfileUpdate.ts new file mode 100644 index 00000000..2c84fb85 --- /dev/null +++ b/packages/components/modules/profiles/graphql/mutations/ProfileUpdate.ts @@ -0,0 +1,20 @@ +import { graphql, useMutation } from 'react-relay' + +import { ProfileUpdateMutation } from '../../../../__generated__/ProfileUpdateMutation.graphql' + +const ProfileUpdateMutationQuery = graphql` + mutation ProfileUpdateMutation($input: ProfileUpdateInput!) { + profileUpdate(input: $input) { + profile { + ...ProfileComponentFragment + } + errors { + field + messages + } + } + } +` + +export const useProfileMutation = () => + useMutation(ProfileUpdateMutationQuery) diff --git a/packages/components/modules/profiles/graphql/queries/BlockToggle.ts b/packages/components/modules/profiles/graphql/queries/BlockToggle.ts new file mode 100644 index 00000000..4cfae378 --- /dev/null +++ b/packages/components/modules/profiles/graphql/queries/BlockToggle.ts @@ -0,0 +1,12 @@ +import { graphql } from 'relay-runtime' + +export const BlockToggleFragment = graphql` + fragment BlockToggleFragment on BlocksInterface { + id + isBlockedByMe + ... on Profile { + id + name + } + } +` diff --git a/packages/components/modules/profiles/graphql/queries/FollowToggleUpdatableFragment.ts b/packages/components/modules/profiles/graphql/queries/FollowToggleUpdatableFragment.ts new file mode 100644 index 00000000..d8939562 --- /dev/null +++ b/packages/components/modules/profiles/graphql/queries/FollowToggleUpdatableFragment.ts @@ -0,0 +1,8 @@ +import { graphql } from 'relay-runtime' + +export const FollowToggleUpdatableFragment = graphql` + fragment FollowToggleUpdatableFragment on Profile @updatable { + isFollowedByMe + followersCount + } +` diff --git a/packages/components/modules/profiles/graphql/queries/ProfileComponent.ts b/packages/components/modules/profiles/graphql/queries/ProfileComponent.ts new file mode 100644 index 00000000..d781587c --- /dev/null +++ b/packages/components/modules/profiles/graphql/queries/ProfileComponent.ts @@ -0,0 +1,28 @@ +import { graphql } from 'react-relay' + +export const ProfileComponentFragment = graphql` + fragment ProfileComponentFragment on Profile { + id + status + name + biography + image(height: 96, width: 96) { + url + } + bannerImage(height: 290, width: 868) { + url + } + isFollowedByMe + followersCount + followingCount + canChange: hasPerm(perm: "change") + urlPath { + path + } + owner { + phoneNumber + } + isBlockedByMe + ...BlockToggleFragment + } +` diff --git a/packages/components/modules/profiles/index.ts b/packages/components/modules/profiles/index.ts index 47b231a8..355326d9 100644 --- a/packages/components/modules/profiles/index.ts +++ b/packages/components/modules/profiles/index.ts @@ -1,2 +1,4 @@ export * from './ProfilePopover' export { default as Members } from './Members' +export { default as ProfileComponent } from './ProfileComponent' +export type * from './ProfileComponent/types' diff --git a/packages/components/package.json b/packages/components/package.json index e2e1531f..df68ad2c 100644 --- a/packages/components/package.json +++ b/packages/components/package.json @@ -1,7 +1,7 @@ { "name": "@baseapp-frontend/components", "description": "BaseApp components modules such as comments, notifications, messages, and more.", - "version": "0.0.40", + "version": "0.0.41", "main": "./index.ts", "types": "dist/index.d.ts", "sideEffects": false, @@ -37,6 +37,7 @@ "js-cookie": "catalog:", "luxon": "catalog:", "next": "catalog:", + "numbro": "^2.5.0", "react-hook-form": "catalog:", "react-relay": "catalog:graphql", "react-virtuoso": "catalog:", diff --git a/packages/design-system/.storybook/preview.ts b/packages/design-system/.storybook/preview.ts index 250f7bdf..3ac8f16b 100644 --- a/packages/design-system/.storybook/preview.ts +++ b/packages/design-system/.storybook/preview.ts @@ -32,6 +32,8 @@ const preview: Preview = { 'LoadingState', // Drawers 'SwipeableDrawer', + // Images + 'ImageWithFallback', // Popover 'Popover', // Form diff --git a/packages/design-system/CHANGELOG.md b/packages/design-system/CHANGELOG.md index 17e64046..bdbd2ff0 100644 --- a/packages/design-system/CHANGELOG.md +++ b/packages/design-system/CHANGELOG.md @@ -1,5 +1,11 @@ # @baseapp-frontend/design-system +## 0.0.27 + +### Patch Changes + +- Moved BlockIcon, UnblockIcon, ThreeDotsIcon and ImageWithFallback from baseapp-frontend-template + ## 0.0.26 ### Patch Changes diff --git a/packages/design-system/components/icons/BlockIcon/index.tsx b/packages/design-system/components/icons/BlockIcon/index.tsx new file mode 100644 index 00000000..fbef10f6 --- /dev/null +++ b/packages/design-system/components/icons/BlockIcon/index.tsx @@ -0,0 +1,24 @@ +import { FC } from 'react' + +import { SvgIcon, SvgIconProps } from '@mui/material' + +const BlockIcon: FC = ({ sx, ...props }) => ( + + + + + + +) + +export default BlockIcon diff --git a/packages/design-system/components/icons/ThreeDotsIcon/index.tsx b/packages/design-system/components/icons/ThreeDotsIcon/index.tsx new file mode 100644 index 00000000..40695225 --- /dev/null +++ b/packages/design-system/components/icons/ThreeDotsIcon/index.tsx @@ -0,0 +1,33 @@ +import { FC } from 'react' + +import { SvgIcon, SvgIconProps } from '@mui/material' + +const ThreeDotsIcon: FC = ({ sx, ...props }) => ( + + + + + + + +) + +export default ThreeDotsIcon diff --git a/packages/design-system/components/icons/UnblockIcon/index.tsx b/packages/design-system/components/icons/UnblockIcon/index.tsx new file mode 100644 index 00000000..802627ed --- /dev/null +++ b/packages/design-system/components/icons/UnblockIcon/index.tsx @@ -0,0 +1,30 @@ +import { FC } from 'react' + +import { SvgIcon, SvgIconProps } from '@mui/material' + +const UnblockIcon: FC = ({ sx, ...props }) => ( + + + + + + + +) + +export default UnblockIcon diff --git a/packages/design-system/components/icons/index.ts b/packages/design-system/components/icons/index.ts index d1c8732e..22499dca 100644 --- a/packages/design-system/components/icons/index.ts +++ b/packages/design-system/components/icons/index.ts @@ -2,6 +2,7 @@ export { default as AddIcon } from './AddIcon' export { default as ArchiveIcon } from './ArchiveIcon' export { default as AttachmentIcon } from './AttachmentIcon' export { default as BaseAppLogoCondensed } from './BaseAppLogoCondensed' +export { default as BlockIcon } from './BlockIcon' export { default as CheckMarkIcon } from './CheckMarkIcon' export { default as ChevronIcon } from './ChevronIcon' export { default as CloseIcon } from './CloseIcon' @@ -17,6 +18,8 @@ export { default as PenEditIcon } from './PenEditIcon' export { default as PinIcon } from './PinIcon' export { default as SendMessageIcon } from './SendMessageIcon' export { default as ShareIcon } from './ShareIcon' +export { default as ThreeDotsIcon } from './ThreeDotsIcon' export { default as TrashCanIcon } from './TrashCanIcon' export { default as UnarchiveIcon } from './UnarchiveIcon' +export { default as UnblockIcon } from './UnblockIcon' export { default as UnreadIcon } from './UnreadIcon' diff --git a/packages/design-system/components/images/ImageWithFallback/__storybook__/stories.tsx b/packages/design-system/components/images/ImageWithFallback/__storybook__/stories.tsx new file mode 100644 index 00000000..11fa4c52 --- /dev/null +++ b/packages/design-system/components/images/ImageWithFallback/__storybook__/stories.tsx @@ -0,0 +1,26 @@ +import React from 'react' + +import { Meta, StoryFn, StoryObj } from '@storybook/react' + +import ImageWithFallback from '..' +import { ImageWithFallbackProps } from '../types' + +const meta: Meta = { + title: '@baseapp-frontend-template / Design System/Displays/ImageWithFallback', + component: ImageWithFallback, +} + +export default meta + +type Story = StoryObj + +const Template: StoryFn = (args) => + +export const Default: Story = Template.bind({}) +Default.args = { + src: '/webp/home-banner.webp', + fallbackSrc: '/png/home-banner.png', + alt: 'Example image', + width: 400, + height: 300, +} diff --git a/packages/design-system/components/images/ImageWithFallback/index.tsx b/packages/design-system/components/images/ImageWithFallback/index.tsx new file mode 100644 index 00000000..5c69830b --- /dev/null +++ b/packages/design-system/components/images/ImageWithFallback/index.tsx @@ -0,0 +1,36 @@ +import { FC } from 'react' + +import Image from 'next/image' + +import { ImageWithFallbackProps } from './types' + +/** + * This component can have more than one source, offering alternative versions of an image for different display/device scenarios. + * + * It uses, by default, the webp format, but if the browser doesn't support it, it will fall back to png. + * + * @description + * This is a **BaseApp** feature. + * + * Developers can freely edit this to suit the project's needs. + * + * If you believe your changes should be in the BaseApp, please read the **CONTRIBUTING.md** guide. + */ +const ImageWithFallback: FC = ({ + src, + fallbackSrc, + type = 'image/webp', + fallbackType = 'image/png', + alt, + width, + height, + ...props +}) => ( + + + + {alt} + +) + +export default ImageWithFallback diff --git a/packages/design-system/components/images/ImageWithFallback/types.ts b/packages/design-system/components/images/ImageWithFallback/types.ts new file mode 100644 index 00000000..128de52a --- /dev/null +++ b/packages/design-system/components/images/ImageWithFallback/types.ts @@ -0,0 +1,11 @@ +import { ImageProps } from 'next/image' + +export interface ImageWithFallbackProps extends ImageProps { + src: string + fallbackSrc: string + type?: string + fallbackType?: string + alt: string + width: number + height: number +} diff --git a/packages/design-system/components/images/index.ts b/packages/design-system/components/images/index.ts new file mode 100644 index 00000000..6ddce5a4 --- /dev/null +++ b/packages/design-system/components/images/index.ts @@ -0,0 +1 @@ +export { default as ImageWithFallback } from './ImageWithFallback' diff --git a/packages/design-system/index.ts b/packages/design-system/index.ts index ca28fedd..74d72ee2 100644 --- a/packages/design-system/index.ts +++ b/packages/design-system/index.ts @@ -26,6 +26,7 @@ export * from './components/displays' export * from './components/drawers' export * from './components/icons' export * from './components/illustrations' +export * from './components/images' export * from './components/inputs' export * from './components/typographies' diff --git a/packages/design-system/package.json b/packages/design-system/package.json index 99fc94d6..15d8d399 100644 --- a/packages/design-system/package.json +++ b/packages/design-system/package.json @@ -1,7 +1,7 @@ { "name": "@baseapp-frontend/design-system", "description": "Design System components and configurations.", - "version": "0.0.26", + "version": "0.0.27", "main": "./index.ts", "types": "dist/index.d.ts", "sideEffects": false, diff --git a/packages/wagtail/CHANGELOG.md b/packages/wagtail/CHANGELOG.md index 5a8b1d18..4c59e128 100644 --- a/packages/wagtail/CHANGELOG.md +++ b/packages/wagtail/CHANGELOG.md @@ -1,5 +1,12 @@ # @baseapp-frontend/wagtail +## 1.0.12 + +### Patch Changes + +- Updated dependencies + - @baseapp-frontend/design-system@0.0.27 + ## 1.0.11 ### Patch Changes diff --git a/packages/wagtail/package.json b/packages/wagtail/package.json index d7351144..98c24c39 100644 --- a/packages/wagtail/package.json +++ b/packages/wagtail/package.json @@ -1,7 +1,7 @@ { "name": "@baseapp-frontend/wagtail", "description": "BaseApp Wagtail", - "version": "1.0.11", + "version": "1.0.12", "main": "./index.ts", "types": "dist/index.d.ts", "sideEffects": false, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 42e91930..c362955f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -521,6 +521,9 @@ importers: next: specifier: 'catalog:' version: 14.3.0-canary.24(@babel/core@7.26.0)(babel-plugin-macros@3.1.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + numbro: + specifier: ^2.5.0 + version: 2.5.0 react: specifier: catalog:react18 version: 18.3.1 @@ -2156,12 +2159,6 @@ packages: peerDependencies: '@babel/core': ^7.0.0-0 - '@babel/preset-react@7.26.3': - resolution: {integrity: sha512-Nl03d6T9ky516DGK2YMxrTqvnpUW63TnJMOMonj+Zae0JiPC5BC9xPMSL6L8fiSpA5vP88qfygavVQvnLp+6Cw==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - '@babel/preset-typescript@7.26.0': resolution: {integrity: sha512-NMk1IGZ5I/oHhoXEElcm+xUnL/szL6xflkFZmoEU9xj1qSJXpiS7rsspYo92B4DRCDvZn2erT5LdsCeXAKNCkg==} engines: {node: '>=6.9.0'} @@ -4855,6 +4852,9 @@ packages: big.js@5.2.2: resolution: {integrity: sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==} + bignumber.js@9.1.2: + resolution: {integrity: sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -8028,6 +8028,9 @@ packages: nullthrows@1.1.1: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} + numbro@2.5.0: + resolution: {integrity: sha512-xDcctDimhzko/e+y+Q2/8i3qNC9Svw1QgOkSkQoO0kIPI473tR9QRbo2KP88Ty9p8WbPy+3OpTaAIzehtuHq+A==} + nwsapi@2.2.16: resolution: {integrity: sha512-F1I/bimDpj3ncaNDhfyMWuFqmQDBwDB0Fogc2qpL3BWvkQteFD/8BzWuIRl83rq0DXfm8SGt/HFhLXZyljTXcQ==} @@ -10281,7 +10284,7 @@ snapshots: '@babel/generator@7.17.7': dependencies: - '@babel/types': 7.17.0 + '@babel/types': 7.26.3 jsesc: 2.5.2 source-map: 0.5.7 @@ -11117,18 +11120,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/preset-react@7.26.3(@babel/core@7.26.0)': - dependencies: - '@babel/core': 7.26.0 - '@babel/helper-plugin-utils': 7.25.9 - '@babel/helper-validator-option': 7.25.9 - '@babel/plugin-transform-react-display-name': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-react-jsx': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-react-jsx-development': 7.25.9(@babel/core@7.26.0) - '@babel/plugin-transform-react-pure-annotations': 7.25.9(@babel/core@7.26.0) - transitivePeerDependencies: - - supports-color - '@babel/preset-typescript@7.26.0(@babel/core@7.26.0)': dependencies: '@babel/core': 7.26.0 @@ -11483,7 +11474,7 @@ snapshots: dependencies: '@babel/runtime': 7.26.0 '@emotion/babel-plugin': 11.13.5 - '@emotion/cache': 11.11.0 + '@emotion/cache': 11.14.0 '@emotion/serialize': 1.3.3 '@emotion/use-insertion-effect-with-fallbacks': 1.2.0(react@18.3.1) '@emotion/utils': 1.4.2 @@ -12080,7 +12071,7 @@ snapshots: '@jest/console@29.7.0': dependencies: '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.10.2 chalk: 4.1.2 jest-message-util: 29.7.0 jest-util: 29.7.0 @@ -12093,14 +12084,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.10.2 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.7.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.4.5)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -12128,14 +12119,14 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.10.2 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.9.0 exit: 0.1.2 graceful-fs: 4.2.11 jest-changed-files: 29.7.0 - jest-config: 29.7.0(@types/node@22.7.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.7.2)(typescript@5.4.5)) + jest-config: 29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.7.2)(typescript@5.4.5)) jest-haste-map: 29.7.0 jest-message-util: 29.7.0 jest-regex-util: 29.6.3 @@ -12164,7 +12155,7 @@ snapshots: dependencies: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.10.2 jest-mock: 29.7.0 '@jest/expect-utils@29.7.0': @@ -12182,7 +12173,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@sinonjs/fake-timers': 10.3.0 - '@types/node': 22.7.2 + '@types/node': 22.10.2 jest-message-util: 29.7.0 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -12204,7 +12195,7 @@ snapshots: '@jest/transform': 29.7.0 '@jest/types': 29.6.3 '@jridgewell/trace-mapping': 0.3.25 - '@types/node': 22.7.2 + '@types/node': 22.10.2 chalk: 4.1.2 collect-v8-coverage: 1.0.2 exit: 0.1.2 @@ -12274,7 +12265,7 @@ snapshots: '@jest/schemas': 29.6.3 '@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-reports': 3.0.4 - '@types/node': 22.7.2 + '@types/node': 22.10.2 '@types/yargs': 17.0.33 chalk: 4.1.2 @@ -14278,7 +14269,7 @@ snapshots: '@types/graceful-fs@4.1.9': dependencies: - '@types/node': 22.7.2 + '@types/node': 22.10.2 '@types/html-minifier-terser@5.1.2': {} @@ -14311,7 +14302,7 @@ snapshots: '@types/jsdom@20.0.1': dependencies: - '@types/node': 22.7.2 + '@types/node': 22.10.2 '@types/tough-cookie': 4.0.5 parse5: 7.2.1 @@ -15089,7 +15080,7 @@ snapshots: '@babel/plugin-transform-export-namespace-from': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-object-rest-spread': 7.25.9(@babel/core@7.26.0) '@babel/plugin-transform-parameters': 7.25.9(@babel/core@7.26.0) - '@babel/preset-react': 7.26.3(@babel/core@7.26.0) + '@babel/preset-react': 7.25.9(@babel/core@7.26.0) '@babel/preset-typescript': 7.26.0(@babel/core@7.26.0) '@react-native/babel-preset': 0.76.5(@babel/core@7.26.0)(@babel/preset-env@7.26.0(@babel/core@7.26.0)) babel-plugin-react-native-web: 0.19.13 @@ -15131,6 +15122,8 @@ snapshots: big.js@5.2.2: {} + bignumber.js@9.1.2: {} + binary-extensions@2.3.0: {} blob-util@2.0.2: {} @@ -15649,12 +15642,12 @@ snapshots: css-loader@6.11.0(webpack@5.93.0(@swc/core@1.10.4(@swc/helpers@0.5.15))): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) - postcss-modules-local-by-default: 4.2.0(postcss@8.4.38) - postcss-modules-scope: 3.2.1(postcss@8.4.38) - postcss-modules-values: 4.0.0(postcss@8.4.38) + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.49) + postcss-modules-local-by-default: 4.2.0(postcss@8.4.49) + postcss-modules-scope: 3.2.1(postcss@8.4.49) + postcss-modules-values: 4.0.0(postcss@8.4.49) postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: @@ -15662,12 +15655,12 @@ snapshots: css-loader@6.11.0(webpack@5.93.0): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) - postcss-modules-local-by-default: 4.2.0(postcss@8.4.38) - postcss-modules-scope: 3.2.1(postcss@8.4.38) - postcss-modules-values: 4.0.0(postcss@8.4.38) + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.49) + postcss-modules-local-by-default: 4.2.0(postcss@8.4.49) + postcss-modules-scope: 3.2.1(postcss@8.4.49) + postcss-modules-values: 4.0.0(postcss@8.4.49) postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: @@ -15675,12 +15668,12 @@ snapshots: css-loader@7.1.2(webpack@5.93.0(@swc/core@1.10.4(@swc/helpers@0.5.15))): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) - postcss-modules-local-by-default: 4.2.0(postcss@8.4.38) - postcss-modules-scope: 3.2.1(postcss@8.4.38) - postcss-modules-values: 4.0.0(postcss@8.4.38) + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.49) + postcss-modules-local-by-default: 4.2.0(postcss@8.4.49) + postcss-modules-scope: 3.2.1(postcss@8.4.49) + postcss-modules-values: 4.0.0(postcss@8.4.49) postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: @@ -15688,12 +15681,12 @@ snapshots: css-loader@7.1.2(webpack@5.93.0): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 - postcss-modules-extract-imports: 3.1.0(postcss@8.4.38) - postcss-modules-local-by-default: 4.2.0(postcss@8.4.38) - postcss-modules-scope: 3.2.1(postcss@8.4.38) - postcss-modules-values: 4.0.0(postcss@8.4.38) + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 + postcss-modules-extract-imports: 3.1.0(postcss@8.4.49) + postcss-modules-local-by-default: 4.2.0(postcss@8.4.49) + postcss-modules-scope: 3.2.1(postcss@8.4.49) + postcss-modules-values: 4.0.0(postcss@8.4.49) postcss-value-parser: 4.2.0 semver: 7.6.3 optionalDependencies: @@ -17375,9 +17368,9 @@ snapshots: dependencies: safer-buffer: 2.1.2 - icss-utils@5.1.0(postcss@8.4.38): + icss-utils@5.1.0(postcss@8.4.49): dependencies: - postcss: 8.4.38 + postcss: 8.4.49 ieee754@1.2.1: {} @@ -17711,7 +17704,7 @@ snapshots: '@jest/expect': 29.7.0 '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.10.2 chalk: 4.1.2 co: 4.6.0 dedent: 1.5.3(babel-plugin-macros@3.1.0) @@ -17800,7 +17793,7 @@ snapshots: - babel-plugin-macros - supports-color - jest-config@29.7.0(@types/node@22.7.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.4.5)): + jest-config@29.7.0(@types/node@22.10.2)(babel-plugin-macros@3.1.0)(ts-node@10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.7.2)(typescript@5.4.5)): dependencies: '@babel/core': 7.26.0 '@jest/test-sequencer': 29.7.0 @@ -17825,8 +17818,8 @@ snapshots: slash: 3.0.0 strip-json-comments: 3.1.1 optionalDependencies: - '@types/node': 22.7.2 - ts-node: 10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.4.5) + '@types/node': 22.10.2 + ts-node: 10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.7.2)(typescript@5.4.5) transitivePeerDependencies: - babel-plugin-macros - supports-color @@ -17887,7 +17880,7 @@ snapshots: '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 '@types/jsdom': 20.0.1 - '@types/node': 22.7.2 + '@types/node': 22.10.2 jest-mock: 29.7.0 jest-util: 29.7.0 jsdom: 20.0.3 @@ -17901,7 +17894,7 @@ snapshots: '@jest/environment': 29.7.0 '@jest/fake-timers': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.10.2 jest-mock: 29.7.0 jest-util: 29.7.0 @@ -17911,7 +17904,7 @@ snapshots: dependencies: '@jest/types': 29.6.3 '@types/graceful-fs': 4.1.9 - '@types/node': 22.7.2 + '@types/node': 22.10.2 anymatch: 3.1.3 fb-watchman: 2.0.2 graceful-fs: 4.2.11 @@ -17950,7 +17943,7 @@ snapshots: jest-mock@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.10.2 jest-util: 29.7.0 jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): @@ -17985,7 +17978,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.10.2 chalk: 4.1.2 emittery: 0.13.1 graceful-fs: 4.2.11 @@ -18013,7 +18006,7 @@ snapshots: '@jest/test-result': 29.7.0 '@jest/transform': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.10.2 chalk: 4.1.2 cjs-module-lexer: 1.4.1 collect-v8-coverage: 1.0.2 @@ -18059,7 +18052,7 @@ snapshots: jest-util@29.7.0: dependencies: '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.10.2 chalk: 4.1.2 ci-info: 3.9.0 graceful-fs: 4.2.11 @@ -18078,7 +18071,7 @@ snapshots: dependencies: '@jest/test-result': 29.7.0 '@jest/types': 29.6.3 - '@types/node': 22.7.2 + '@types/node': 22.10.2 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.13.1 @@ -18093,7 +18086,7 @@ snapshots: jest-worker@29.7.0: dependencies: - '@types/node': 22.7.2 + '@types/node': 22.10.2 jest-util: 29.7.0 merge-stream: 2.0.0 supports-color: 8.1.1 @@ -19033,6 +19026,10 @@ snapshots: nullthrows@1.1.1: {} + numbro@2.5.0: + dependencies: + bignumber.js: 9.1.2 + nwsapi@2.2.16: {} ob1@0.81.0: @@ -19376,24 +19373,24 @@ snapshots: possible-typed-array-names@1.0.0: {} - postcss-import@15.1.0(postcss@8.4.38): + postcss-import@15.1.0(postcss@8.4.49): dependencies: - postcss: 8.4.38 + postcss: 8.4.49 postcss-value-parser: 4.2.0 read-cache: 1.0.0 resolve: 1.22.10 - postcss-js@4.0.1(postcss@8.4.38): + postcss-js@4.0.1(postcss@8.4.49): dependencies: camelcase-css: 2.0.1 - postcss: 8.4.38 + postcss: 8.4.49 - postcss-load-config@4.0.2(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.4.5)): + postcss-load-config@4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.4.5)): dependencies: lilconfig: 3.1.3 yaml: 2.6.1 optionalDependencies: - postcss: 8.4.38 + postcss: 8.4.49 ts-node: 10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.4.5) postcss-loader@8.1.1(postcss@8.4.38)(typescript@5.4.5)(webpack@5.93.0(@swc/core@1.10.4(@swc/helpers@0.5.15))): @@ -19418,30 +19415,30 @@ snapshots: transitivePeerDependencies: - typescript - postcss-modules-extract-imports@3.1.0(postcss@8.4.38): + postcss-modules-extract-imports@3.1.0(postcss@8.4.49): dependencies: - postcss: 8.4.38 + postcss: 8.4.49 - postcss-modules-local-by-default@4.2.0(postcss@8.4.38): + postcss-modules-local-by-default@4.2.0(postcss@8.4.49): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 postcss-selector-parser: 7.0.0 postcss-value-parser: 4.2.0 - postcss-modules-scope@3.2.1(postcss@8.4.38): + postcss-modules-scope@3.2.1(postcss@8.4.49): dependencies: - postcss: 8.4.38 + postcss: 8.4.49 postcss-selector-parser: 7.0.0 - postcss-modules-values@4.0.0(postcss@8.4.38): + postcss-modules-values@4.0.0(postcss@8.4.49): dependencies: - icss-utils: 5.1.0(postcss@8.4.38) - postcss: 8.4.38 + icss-utils: 5.1.0(postcss@8.4.49) + postcss: 8.4.49 - postcss-nested@6.2.0(postcss@8.4.38): + postcss-nested@6.2.0(postcss@8.4.49): dependencies: - postcss: 8.4.38 + postcss: 8.4.49 postcss-selector-parser: 6.1.2 postcss-selector-parser@6.0.10: @@ -20590,11 +20587,11 @@ snapshots: normalize-path: 3.0.0 object-hash: 3.0.0 picocolors: 1.1.1 - postcss: 8.4.38 - postcss-import: 15.1.0(postcss@8.4.38) - postcss-js: 4.0.1(postcss@8.4.38) - postcss-load-config: 4.0.2(postcss@8.4.38)(ts-node@10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.4.5)) - postcss-nested: 6.2.0(postcss@8.4.38) + postcss: 8.4.49 + postcss-import: 15.1.0(postcss@8.4.49) + postcss-js: 4.0.1(postcss@8.4.49) + postcss-load-config: 4.0.2(postcss@8.4.49)(ts-node@10.9.2(@swc/core@1.10.4(@swc/helpers@0.5.15))(@types/node@22.10.2)(typescript@5.4.5)) + postcss-nested: 6.2.0(postcss@8.4.49) postcss-selector-parser: 6.1.2 resolve: 1.22.10 sucrase: 3.35.0