> ## Documentation Index
> Fetch the complete documentation index at: https://docs.twenty.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ResizeHandle

> غيّر حجم لوحة بالسحب بالمؤشر أو باستخدام عناصر التحكم بلوحة المفاتيح.

## نظرة عامة

يدير `ResizeHandle` حجمًا رقميًا ويعرض فاصلًا قابلًا للتركيز. يطبّق التطبيق ذلك الحجم على اللوحة؛ ولا يغيّر المقبض حجم عنصر آخر تلقائيًا.

**Light**

[مثال على ResizeHandle (light)](https://storybook.twenty.com/iframe.html?id=ui-layout-resizehandle--display\&viewMode=story\&globals=colorScheme:light)

**Dark**

[مثال على ResizeHandle (dark)](https://storybook.twenty.com/iframe.html?id=ui-layout-resizehandle--display\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-layout-resizehandle--display)

## استخدام

استخدم `edge` لحدود اللوحة، أو `axis="y"` لتغيير حجم الارتفاع المضمّن و`axis="x"` لتغيير حجم العرض المضمّن. امنح المقبض اسمًا محددًا لإمكانية الوصول، واستخدم `aria-controls` لتحديد اللوحة.

```tsx theme={null}
import { useId, useState } from 'react';
import { ResizeHandle } from 'twenty-ui/primitives/layout';
import { Card } from 'twenty-ui/primitives/surfaces';
import { Text } from 'twenty-ui/primitives/typography';

export const ResizableNotes = () => {
  const panelId = useId();
  const [height, setHeight] = useState(150);

  return (
    <Card.Root style={{ width: 300, maxWidth: '100%' }}>
      <Text
        id={panelId}
        style={{
          height,
          overflow: 'auto',
          padding: 16,
          boxSizing: 'border-box',
        }}
      >
        <Text
          style={{
            color: 'var(--t-font-color-primary)',
            fontWeight: 'var(--t-font-weight-medium)',
          }}
        >
          Record notes
        </Text>
        <Text style={{ marginTop: 8, lineHeight: 1.5 }}>
          Follow up with Morgan about the proposal. Share the revised timeline
          before Friday.
        </Text>
      </Text>
      <Text style={{ padding: 4 }}>
        <ResizeHandle
          axis="y"
          defaultValue={150}
          onValueChange={setHeight}
          min={50}
          max={500}
          aria-label="Resize notes height"
          aria-controls={panelId}
        />
      </Text>
    </Card.Root>
  );
};
```

يمتلك المقبض قيمته. ينسخ `onValueChange` أحدث حجم إلى تخطيط اللوحة دون التحكم بالمقبض. لا يضبط `defaultValue` سوى الحجم الأولي.

## الحالة المتحكَّم بها

```tsx theme={null}
import { useId, useState } from 'react';
import { ResizeHandle } from 'twenty-ui/primitives/layout';
import { Card } from 'twenty-ui/primitives/surfaces';
import { Text } from 'twenty-ui/primitives/typography';

export const ResizableNotes = () => {
  const panelId = useId();
  const [height, setHeight] = useState(150);

  return (
    <Card.Root style={{ width: 300, maxWidth: '100%' }}>
      <Text
        id={panelId}
        style={{
          height,
          overflow: 'auto',
          padding: 16,
          boxSizing: 'border-box',
        }}
      >
        <Text
          style={{
            color: 'var(--t-font-color-primary)',
            fontWeight: 'var(--t-font-weight-medium)',
          }}
        >
          Record notes
        </Text>
        <Text style={{ marginTop: 8, lineHeight: 1.5 }}>
          Follow up with Morgan about the proposal. Share the revised timeline
          before Friday.
        </Text>
      </Text>
      <Text style={{ padding: 4 }}>
        <ResizeHandle
          axis="y"
          value={height}
          onValueChange={setHeight}
          min={50}
          max={500}
          aria-label="Resize notes height"
          aria-controls={panelId}
        />
      </Text>
    </Card.Root>
  );
};
```

يمتلك التطبيق القيمة ويمكنه تحديثها من عناصر تحكم أخرى. اعكس التغييرات المباشرة في `value`؛ واستخدم `onValueCommitted` لحفظ الحجم النهائي. أبقِ `value` و`defaultValue` منفصلين، وحافظ على نمط الملكية نفسه طوال دورة حياة المكوّن.

## حواف اللوحة والفجوات

يحدّد `edge="left"`, `"right"`, `"top"` or `"bottom"` كلاً من المحور والاتجاه المادي للزيادة. تؤدي الحركة إلى اليسار إلى زيادة الحافة اليسرى، وتؤدي الحركة إلى الأعلى إلى زيادة الحافة العلوية، وينطبق العكس على الحافتين اليمنى والسفلية. يبقى هذا السلوك كما هو في المحتوى من اليمين إلى اليسار. استخدم إما `edge` أو `axis` و`direction`.

مع `edge`، يكون الموضع الافتراضي هو `"edge"`. ضع المقبض داخل لوحة ذات `position: 'relative'` لوضعه بمحاذاة ذلك الحد. يبقي `placement="inline"` المقبض في التدفق العادي. استخدم `placement="gap"` بين اللوحات الشقيقة واضبط عرضه أو ارتفاعه عبر `style` عندما يحتاج التخطيط إلى فجوة. لا تحتوي مقابض الفجوات على مقبض إمساك مرئي افتراضياً.

```tsx theme={null}
import { useId, useState } from 'react';
import { ResizeHandle } from 'twenty-ui/primitives/layout';
import { Card } from 'twenty-ui/primitives/surfaces';
import { Text } from 'twenty-ui/primitives/typography';

export const ResizableDetails = ({
  saveWidth,
}: {
  saveWidth: (value: number) => void;
}) => {
  const detailsId = useId();
  const [width, setWidth] = useState(380);

  return (
    <div style={{ display: 'flex', height: 200 }}>
      <Card.Root style={{ flex: 1 }}>
        <Text>Activity</Text>
      </Card.Root>
      <ResizeHandle
        edge="left"
        placement="gap"
        value={width}
        onValueChange={setWidth}
        onValueCommitted={saveWidth}
        min={280}
        max={800}
        style={{ width: 12 }}
        aria-label="Resize details"
        aria-controls={detailsId}
      />
      <Card.Root id={detailsId} style={{ width }}>
        <Text>Details</Text>
      </Card.Root>
    </div>
  );
};
```

**Light**

[مثال على حافة لوحة ResizeHandle (light)](https://storybook.twenty.com/iframe.html?id=ui-layout-resizehandle-panels--documentation\&viewMode=story\&globals=colorScheme:light)

**Dark**

[مثال على حافة لوحة ResizeHandle (dark)](https://storybook.twenty.com/iframe.html?id=ui-layout-resizehandle-panels--documentation\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-layout-resizehandle-panels--documentation)

**Light**

[مثال على فجوة لوحة ResizeHandle (light)](https://storybook.twenty.com/iframe.html?id=ui-layout-resizehandle-panels--gap\&viewMode=story\&globals=colorScheme:light)

**Dark**

[مثال على فجوة لوحة ResizeHandle (dark)](https://storybook.twenty.com/iframe.html?id=ui-layout-resizehandle-panels--gap\&viewMode=story\&globals=colorScheme:dark)

[Open in Storybook](https://storybook.twenty.com/?path=/story/ui-layout-resizehandle-panels--gap)

يمتلك التطبيق التخطيط والحجم المحفوظ وحالة الطي ووجهة التركيز عندما تؤدي عملية الطي إلى إزالة المقبض. استخدم `onActivate` لإجراء طي اختياري.

## لوحة المفاتيح والحدود

بالنسبة إلى `axis="y"`، يزيد السهم لأسفل الحجم ويقلله السهم لأعلى. بالنسبة إلى `axis="x"`، يزيد «يمين» ويقلل «يسار» في المحتوى من اليسار إلى اليمين؛ وتنعكس الاتجاهات عند استخدام [موفر الاتجاه](https://docs.twenty.com/ar/ui/primitives/layout/direction-provider.md) مع `direction="rtl"`.

تستخدم مفاتيح الأسهم `step`، وقيمته الافتراضية هي `10`. ينتقل Home إلى `min`، وينتقل End إلى `max`. يتم تجاهل المفاتيح المضغوطة مع Alt أو Control أو Meta. يستخدم السحب بالمؤشر الحركة بالبكسل ولا يلتزم بـ `step`. يبقى كلا التفاعلين ضمن الحدود. لا تنقل ضغطات المؤشر التركيز؛ ويصل مستخدمو لوحة المفاتيح إلى المقبض باستخدام Tab. يمنع `disabled` تغيير الحجم ويزيل المقبض من ترتيب التنقل بمفتاح Tab.

يصف اتجاه الفاصل الحافة الفاصلة: أفقي لتغيير الارتفاع وعمودي لتغيير العرض.

## الاتجاهات المادية والتكبير

عيّن `direction="normal"` أو `direction="reverse"` عندما يجب أن تتبع زيادة الحجم اتجاها ماديا ثابتا، بغض النظر عن اتجاه النص. يزداد الحجم في الوضع العادي مع الحركة نحو اليمين أو الأسفل. يزداد الحجم في الوضع العكسي مع الحركة نحو اليسار أو الأعلى. احذف `direction` للاحتفاظ بسلوك اتجاه النص الموضح أعلاه.

يقبل `scale` عامل تكبير موجبا أو دالة تعيد واحدا. يأخذ المقبض عينة منه عند ضغط المؤشر ويقسم حركة المؤشر على تلك القيمة. تبقى خطوات لوحة المفاتيح دون تغيير.

## دورة حياة الإيماءة

يبلغ `onValueChange` عن القيم المباشرة. يبلغ `onValueCommitted` عن القيمة النهائية بعد سحب ناجح بالمؤشر أو تغيير فعّال بلوحة المفاتيح. تلتزم مفاتيح Home وEnd والأسهم فورا عندما تغيّر الحجم.

يتلقى `onResizeStart` أول قيمة مرشحة ضمن الحدود بعد أن يتجاوز المؤشر `dragThreshold`. تكون قيمة الحد الافتراضية `5` مع `edge` و`0` بخلاف ذلك، وتقاس بالبكسلات المادية. يتلقى `onResizeEnd` القيمة `{ cancelled, value }` لسحب بدأ بالفعل. تلغي Escape وإلغاء المؤشر وفقدان التقاط المؤشر وإلغاء التركيب الإيماءة دون التزام؛ ويؤدي تعطيل المقبض إلى إلغائها عند حدث المؤشر التالي له. يستدعي الإلغاء `onValueChange` بقيمة البداية، مع تقييدها بالحدود الحالية. يتلقى `onResizeEnd` تلك القيمة المستعادة.

وفّر `onActivate` لمعالجة نقرة دون سحب، أو Enter أو Space. يمنع تجاوز الحد نقرة المؤشر التالية من التفعيل، حتى عندما يعود المؤشر إلى موضع بدايته.

تعمل المعالجات الأصلية قبل تفاعل المقبض. يؤدي استدعاء `preventDefault()` في `onPointerDown` أو `onKeyDown` إلى تخطي ذلك التفاعل. يؤدي منع `onPointerMove` إلى تخطي ذلك التحديث فقط وإبقاء الإيماءة نشطة. يؤدي منع `onPointerUp` إلى إلغاء السحب واستعادة القيمة المحددة الابتدائية وتخطي `onValueCommitted`. يظل إلغاء المؤشر وفقدان الالتقاط ينهيان الإيماءة.

## مقبض مخصص

تستهدف `ref` والسمات الأصلية و`className` و`style` ومعالجات الأحداث الأصلية جذر الفاصل، وهو `div` افتراضياً. لا يستهدف المرجع اللوحة التي تم تغيير حجمها أو مقبض السحب المرئي.

يستبدل `children` قبضة الإمساك المرئية، ويخفيها `children={null}`؛ ولا يستبدل سلوك الفاصل. يمكن لـ`render` استبدال العنصر الجذر، وعندها يستهدف المرجع ذلك البديل. يجب على الأغلفة المخصصة [تمرير الخصائص والمرجع المقدّمين](https://docs.twenty.com/ar/ui/primitives/overview#custom-components) لكي تصل خصائص التركيز والتقاط المؤشر ومعالجات لوحة المفاتيح وسمات إمكانية الوصول إلى العنصر نفسه.

## الخصائص

**axis** `"x" | "y"` (default: y without edge)

Pointer movement axis without `edge`: `y` for height or `x` for width.

**defaultValue** `number | (readonly string[] & number)` (default: 150)

Initial size when the handle owns its state.

**direction** `"normal" | "reverse"`

Physical increasing direction. Omit to follow the horizontal text direction; use `normal` or `reverse` for a fixed physical edge.

**disabled** `boolean` (default: false)

Disables resizing and removes the handle from the tab order.

**dragThreshold** `number` (default: 5 with edge; 0 otherwise)

Physical pointer distance required before resizing starts. Movement below the threshold remains a click. Defaults to 5 with `edge` and 0 otherwise.

**edge** `"bottom" | "left" | "right" | "top"`

Physical panel edge. Determines the movement axis and increasing direction, independently of text direction.

**max** `number` (default: 500)

Maximum allowed size.

**min** `number` (default: 50)

Minimum allowed size.

**onActivate** `(() =\> void)`

Called for a click without dragging, Enter, or Space.

**onResizeEnd** `((details: \{ cancelled: boolean; value: number; \}) =\> void)`

Called after a started drag ends, with its final value and whether it was cancelled. Cancellation restores the starting value within the current bounds.

**onResizeStart** `((value: number) =\> void)`

Called once with the first bounded drag value after the threshold is crossed.

**onValueChange** `((value: number) =\> void)`

Called with the bounded size during pointer or keyboard interaction and with the restored value on cancellation.

**onValueCommitted** `((value: number) =\> void)`

Called with the final size after a successful drag or an effective keyboard size change. Cancellation does not commit.

**placement** `"edge" | "gap" | "inline"` (default: edge with edge; inline otherwise)

Layout mode: `inline` stays in normal flow, `edge` positions the handle on the panel edge, and `gap` sits between panels. Defaults to `edge` when `edge` is set and `inline` otherwise.

**render** `ReactElement\<unknown, string | JSXElementConstructor\<any\>\> | ComponentRenderFn\<HTMLProps, \{\}\>`

Allows you to replace the component's HTML element
with a different tag, or compose it with another component.

Accepts a `ReactElement` or a function that returns the element to render.

**scale** `number | (() =\> number)` (default: 1)

Pointer scale or resolver sampled at pointer down. Movement is divided by this positive scale; keyboard steps are unchanged.

**step** `number` (default: 10)

Keyboard arrow increment. Pointer movement uses the pixel delta.

**value** `number`

Current controlled size. Update it in `onValueChange` and apply it to the element being resized.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.