From af66aa0d95dc692b1c25aab6c223de2470bc869e Mon Sep 17 00:00:00 2001
From: neverland <chenjiahan@youzan.com>
Date: Tue, 29 Jun 2021 20:37:32 +0800
Subject: [PATCH] feat(Cascader): add disabled option (#8952)

---
 src/cascader/Cascader.tsx    | 13 ++++++++++++-
 src/cascader/README.md       | 15 ++++++++-------
 src/cascader/README.zh-CN.md |  2 ++
 src/cascader/index.less      | 10 ++++++++++
 src/cascader/var.less        |  1 +
 5 files changed, 33 insertions(+), 8 deletions(-)

diff --git a/src/cascader/Cascader.tsx b/src/cascader/Cascader.tsx
index e63a7df59..21cbca109 100644
--- a/src/cascader/Cascader.tsx
+++ b/src/cascader/Cascader.tsx
@@ -12,6 +12,7 @@ export type CascaderOption = {
   text?: string;
   value?: string | number;
   color?: string;
+  disabled?: boolean;
   children?: CascaderOption[];
   className?: unknown;
   // for custom filed names
@@ -144,6 +145,10 @@ export default defineComponent({
     };
 
     const onSelect = (option: CascaderOption, tabIndex: number) => {
+      if (option.disabled) {
+        return;
+      }
+
       state.tabs[tabIndex].selectedOption = option;
 
       if (state.tabs.length > tabIndex + 1) {
@@ -218,7 +223,13 @@ export default defineComponent({
 
         return (
           <li
-            class={[bem('option', { selected: isSelected }), option.className]}
+            class={[
+              bem('option', {
+                selected: isSelected,
+                disabled: option.disabled,
+              }),
+              option.className,
+            ]}
             style={{ color }}
             onClick={() => onSelect(option, tabIndex)}
           >
diff --git a/src/cascader/README.md b/src/cascader/README.md
index 6deef7301..dd2ab62df 100644
--- a/src/cascader/README.md
+++ b/src/cascader/README.md
@@ -215,13 +215,14 @@ export default {
 
 ### Data Structure of Option
 
-| Key                | Description              | Type                        |
-| ------------------ | ------------------------ | --------------------------- |
-| text               | Option text              | _string_                    |
-| value              | Option value             | _string \| number_          |
-| color `v3.1.0`     | Text color               | _string_                    |
-| children           | Cascade children         | _Option[]_                  |
-| className `v3.1.0` | className for the option | _string \| Array \| object_ |
+| Key                | Description               | Type                        |
+| ------------------ | ------------------------- | --------------------------- |
+| text               | Option text               | _string_                    |
+| value              | Option value              | _string \| number_          |
+| color `v3.1.0`     | Text color                | _string_                    |
+| children           | Cascade children          | _Option[]_                  |
+| disabled `v3.1.2`  | Whether to disable option | _boolean_                   |
+| className `v3.1.0` | className for the option  | _string \| Array \| object_ |
 
 ### Events
 
diff --git a/src/cascader/README.zh-CN.md b/src/cascader/README.zh-CN.md
index d8073082a..6f346fe31 100644
--- a/src/cascader/README.zh-CN.md
+++ b/src/cascader/README.zh-CN.md
@@ -233,6 +233,7 @@ export default {
 | value              | 选项对应的值(必填)     | _string \| number_          |
 | color `v3.1.0`     | 选项文字颜色             | _string_                    |
 | children           | 子选项列表               | _Option[]_                  |
+| disabled `v3.1.2`  | 是否禁用选项             | _boolean_                   |
 | className `v3.1.0` | 为对应列添加额外的 class | _string \| Array \| object_ |
 
 ### Events
@@ -267,5 +268,6 @@ export default {
 | --van-cascader-tabs-height             | _48px_                    | -    |
 | --van-cascader-active-color            | _var(--van-danger-color)_ | -    |
 | --van-cascader-options-height          | _384px_                   | -    |
+| --van-cascader-option-disabled-color   | _van(--van-gray-5)_       | -    |
 | --van-cascader-tab-color               | _var(--van-text-color)_   | -    |
 | --van-cascader-unselected-tab-color    | _var(--van-gary-6)_       | -    |
diff --git a/src/cascader/index.less b/src/cascader/index.less
index d76f502d3..102115232 100644
--- a/src/cascader/index.less
+++ b/src/cascader/index.less
@@ -12,6 +12,7 @@
   --van-cascader-tabs-height: @cascader-tabs-height;
   --van-cascader-active-color: @cascader-active-color;
   --van-cascader-options-height: @cascader-options-height;
+  --van-cascader-option-disabled-color: @cascader-option-disabled-color;
   --van-cascader-tab-color: @cascader-tab-color;
   --van-cascader-unselected-tab-color: @cascader-unselected-tab-color;
 }
@@ -82,6 +83,15 @@
       color: var(--van-cascader-active-color);
       font-weight: var(--van-font-weight-bold);
     }
+
+    &--disabled {
+      color: var(--van-cascader-option-disabled-color);
+      cursor: not-allowed;
+
+      &:active {
+        background-color: transparent;
+      }
+    }
   }
 
   &__selected-icon {
diff --git a/src/cascader/var.less b/src/cascader/var.less
index c4d02dac7..684b737eb 100644
--- a/src/cascader/var.less
+++ b/src/cascader/var.less
@@ -11,5 +11,6 @@
 @cascader-tabs-height: 48px;
 @cascader-active-color: var(--van-danger-color);
 @cascader-options-height: 384px;
+@cascader-option-disabled-color: var(--van-gray-5);
 @cascader-tab-color: var(--van-text-color);
 @cascader-unselected-tab-color: var(--van-gray-6);